diff libfaad2/syntax.c @ 12527:4a370c80fe5c

update to the 2.0 release of faad, patch by adland
author diego
date Wed, 02 Jun 2004 22:59:04 +0000
parents 3185f64f6350
children d81145997036
line wrap: on
line diff
--- a/libfaad2/syntax.c	Wed Jun 02 22:52:00 2004 +0000
+++ b/libfaad2/syntax.c	Wed Jun 02 22:59:04 2004 +0000
@@ -1,6 +1,6 @@
 /*
 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** 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
@@ -22,7 +22,7 @@
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** $Id: syntax.c,v 1.56 2003/09/30 12:43:05 menno Exp $
+** $Id: syntax.c,v 1.2 2003/10/03 22:22:27 alex Exp $
 **/
 
 /*
@@ -51,6 +51,52 @@
 #endif
 
 
+/* static function declarations */
+static void decode_sce_lfe(faacDecHandle hDecoder, faacDecFrameInfo *hInfo, bitfile *ld,
+                           uint8_t id_syn_ele);
+static void decode_cpe(faacDecHandle hDecoder, faacDecFrameInfo *hInfo, bitfile *ld,
+                       uint8_t id_syn_ele);
+static uint8_t single_lfe_channel_element(faacDecHandle hDecoder, bitfile *ld,
+                                          uint8_t channel, uint8_t *tag);
+static uint8_t channel_pair_element(faacDecHandle hDecoder, bitfile *ld,
+                                    uint8_t channel, uint8_t *tag);
+#ifdef COUPLING_DEC
+static uint8_t coupling_channel_element(faacDecHandle hDecoder, bitfile *ld);
+#endif
+static uint16_t data_stream_element(faacDecHandle hDecoder, bitfile *ld);
+static uint8_t program_config_element(program_config *pce, bitfile *ld);
+static uint8_t fill_element(faacDecHandle hDecoder, bitfile *ld, drc_info *drc
+#ifdef SBR_DEC
+                            ,uint8_t sbr_ele
+#endif
+                            );
+static uint8_t individual_channel_stream(faacDecHandle hDecoder, element *ele,
+                                         bitfile *ld, ic_stream *ics, uint8_t scal_flag,
+                                         int16_t *spec_data);
+static uint8_t ics_info(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld,
+                        uint8_t common_window);
+static uint8_t section_data(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld);
+static uint8_t scale_factor_data(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld);
+#ifdef SSR_DEC
+static void gain_control_data(bitfile *ld, ic_stream *ics);
+#endif
+static uint8_t spectral_data(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld,
+                             int16_t *spectral_data);
+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);
+static uint8_t ltp_data(faacDecHandle hDecoder, ic_stream *ics, ltp_info *ltp, bitfile *ld);
+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);
+static uint8_t dynamic_range_info(bitfile *ld, drc_info *drc);
+static uint8_t excluded_channels(bitfile *ld, drc_info *drc);
+#ifdef SCALABLE_DEC
+static int8_t aac_scalable_main_header(faacDecHandle hDecoder, ic_stream *ics1, ic_stream *ics2,
+                                       bitfile *ld, uint8_t this_layer_stereo);
+#endif
+
+
 /* Table 4.4.1 */
 int8_t GASpecificConfig(bitfile *ld, mp4AudioSpecificConfig *mp4ASC,
                         program_config *pce_out)
@@ -60,6 +106,10 @@
     /* 1024 or 960 */
     mp4ASC->frameLengthFlag = faad_get1bit(ld
         DEBUGVAR(1,138,"GASpecificConfig(): FrameLengthFlag"));
+#ifndef ALLOW_SMALL_FRAMELENGTH
+    if (mp4ASC->frameLengthFlag == 1)
+        return -3;
+#endif
 
     mp4ASC->dependsOnCoreCoder = faad_get1bit(ld
         DEBUGVAR(1,139,"GASpecificConfig(): DependsOnCoreCoder"));
@@ -72,7 +122,8 @@
     mp4ASC->extensionFlag = faad_get1bit(ld DEBUGVAR(1,141,"GASpecificConfig(): ExtensionFlag"));
     if (mp4ASC->channelsConfiguration == 0)
     {
-        program_config_element(&pce, ld);
+        if (program_config_element(&pce, ld))
+            return -3;
         //mp4ASC->channelsConfiguration = pce.channels;
 
         if (pce_out != NULL)
@@ -112,7 +163,7 @@
    PCEs transmitted in raw data blocks cannot be used to convey decoder
    configuration information.
 */
-uint8_t program_config_element(program_config *pce, bitfile *ld)
+static uint8_t program_config_element(program_config *pce, bitfile *ld)
 {
     uint8_t i;
 
@@ -257,108 +308,109 @@
     }
     pce->comment_field_data[i] = 0;
 
+    if (pce->channels > MAX_CHANNELS)
+        return 22;
+
     return 0;
 }
 
-element *decode_sce_lfe(faacDecHandle hDecoder,
-                        faacDecFrameInfo *hInfo, bitfile *ld,
-                        real_t **spec_coef, uint8_t id_syn_ele)
+static void decode_sce_lfe(faacDecHandle hDecoder,
+                           faacDecFrameInfo *hInfo, bitfile *ld,
+                           uint8_t id_syn_ele)
 {
-    element *ele;
     uint8_t channels = hDecoder->fr_channels;
+    uint8_t tag = 0;
 
     if (channels+1 > MAX_CHANNELS)
     {
         hInfo->error = 12;
-        return NULL;
+        return;
     }
     if (hDecoder->fr_ch_ele+1 > MAX_SYNTAX_ELEMENTS)
     {
         hInfo->error = 13;
-        return NULL;
+        return;
     }
 
-    spec_coef[channels]   = (real_t*)malloc(hDecoder->frameLength*sizeof(real_t));
+    /* for SCE hDecoder->element_output_channels[] is not set here because this
+       can become 2 when some form of Parametric Stereo coding is used
+    */
 
-    ele = (element*)malloc(sizeof(element));
-    memset(ele, 0, sizeof(element));
-    ele->ele_id  = id_syn_ele;
-    ele->channel = channels;
-    ele->paired_channel = -1;
+    /* save the syntax element id */
+    hDecoder->element_id[hDecoder->fr_ch_ele] = id_syn_ele;
 
-    hInfo->error = single_lfe_channel_element(hDecoder, ele,
-        ld, spec_coef[channels]);
+    /* decode the element */
+    hInfo->error = single_lfe_channel_element(hDecoder, ld, channels, &tag);
 
-    if (hDecoder->pce_set)
-        hDecoder->internal_channel[hDecoder->pce.sce_channel[ele->element_instance_tag]] = channels;
-    else
+    /* map output channels position to internal data channels */
+    if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 2)
+    {
+        /* this might be faulty when pce_set is true */
         hDecoder->internal_channel[channels] = channels;
+        hDecoder->internal_channel[channels+1] = channels+1;
+    } else {
+        if (hDecoder->pce_set)
+            hDecoder->internal_channel[hDecoder->pce.sce_channel[tag]] = channels;
+        else
+            hDecoder->internal_channel[channels] = channels;
+    }
 
-    if (id_syn_ele == ID_SCE)
-        hDecoder->channel_element[channels] = hDecoder->fr_ch_ele;
-    else /* LFE */
-        hDecoder->channel_element[channels] = hDecoder->fr_ch_ele;
-
-    hDecoder->fr_channels++;
+    hDecoder->fr_channels += hDecoder->element_output_channels[hDecoder->fr_ch_ele];
     hDecoder->fr_ch_ele++;
-
-    return ele;
 }
 
-element *decode_cpe(faacDecHandle hDecoder,
-                    faacDecFrameInfo *hInfo, bitfile *ld,
-                    real_t **spec_coef, uint8_t id_syn_ele)
+static void decode_cpe(faacDecHandle hDecoder, faacDecFrameInfo *hInfo, bitfile *ld,
+                       uint8_t id_syn_ele)
 {
-    element *ele;
     uint8_t channels = hDecoder->fr_channels;
+    uint8_t tag = 0;
 
     if (channels+2 > MAX_CHANNELS)
     {
         hInfo->error = 12;
-        return NULL;
+        return;
     }
     if (hDecoder->fr_ch_ele+1 > MAX_SYNTAX_ELEMENTS)
     {
         hInfo->error = 13;
-        return NULL;
+        return;
     }
 
-    spec_coef[channels]   = (real_t*)malloc(hDecoder->frameLength*sizeof(real_t));
-    spec_coef[channels+1] = (real_t*)malloc(hDecoder->frameLength*sizeof(real_t));
+    /* for CPE the number of output channels is always 2 */
+    if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 0)
+    {
+        /* element_output_channels not set yet */
+        hDecoder->element_output_channels[hDecoder->fr_ch_ele] = 2;
+    } else if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] != 2) {
+        /* element inconsistency */
+        hInfo->error = 21;
+        return;
+    }
 
-    ele = (element*)malloc(sizeof(element));
-    memset(ele, 0, sizeof(element));
-    ele->ele_id         = id_syn_ele;
-    ele->channel        = channels;
-    ele->paired_channel = channels+1;
+    /* save the syntax element id */
+    hDecoder->element_id[hDecoder->fr_ch_ele] = id_syn_ele;
 
-    hInfo->error = channel_pair_element(hDecoder, ele,
-        ld, spec_coef[channels], spec_coef[channels+1]);
+    /* decode the element */
+    hInfo->error = channel_pair_element(hDecoder, ld, channels, &tag);
 
+    /* map output channel position to internal data channels */
     if (hDecoder->pce_set)
     {
-        hDecoder->internal_channel[hDecoder->pce.cpe_channel[ele->element_instance_tag]] = channels;
-        hDecoder->internal_channel[hDecoder->pce.cpe_channel[ele->element_instance_tag]+1] = channels+1;
+        hDecoder->internal_channel[hDecoder->pce.cpe_channel[tag]] = channels;
+        hDecoder->internal_channel[hDecoder->pce.cpe_channel[tag]+1] = channels+1;
     } else {
         hDecoder->internal_channel[channels] = channels;
         hDecoder->internal_channel[channels+1] = channels+1;
     }
 
-    hDecoder->channel_element[channels] = hDecoder->fr_ch_ele;
-    hDecoder->channel_element[channels+1] = hDecoder->fr_ch_ele;
-
     hDecoder->fr_channels += 2;
     hDecoder->fr_ch_ele++;
-
-    return ele;
 }
 
-element **raw_data_block(faacDecHandle hDecoder, faacDecFrameInfo *hInfo,
-                         bitfile *ld, element **elements,
-                         real_t **spec_coef, program_config *pce, drc_info *drc)
+void raw_data_block(faacDecHandle hDecoder, faacDecFrameInfo *hInfo,
+                    bitfile *ld, program_config *pce, drc_info *drc)
 {
     uint8_t id_syn_ele;
-    uint8_t ch_ele = 0;
 
     hDecoder->fr_channels = 0;
     hDecoder->fr_ch_ele = 0;
@@ -376,56 +428,52 @@
             switch (id_syn_ele) {
             case ID_SCE:
                 if (hDecoder->first_syn_ele == 25) hDecoder->first_syn_ele = id_syn_ele;
-                hDecoder->last_syn_ele = id_syn_ele;
-                elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                    hInfo, ld, spec_coef, id_syn_ele);
+                decode_sce_lfe(hDecoder, hInfo, ld, id_syn_ele);
                 if (hInfo->error > 0)
-                    return elements;
+                    return;
                 break;
             case ID_CPE:
                 if (hDecoder->first_syn_ele == 25) hDecoder->first_syn_ele = id_syn_ele;
-                hDecoder->last_syn_ele = id_syn_ele;
-                elements[ch_ele++] = decode_cpe(hDecoder,
-                    hInfo, ld, spec_coef, id_syn_ele);
+                decode_cpe(hDecoder, hInfo, ld, id_syn_ele);
                 if (hInfo->error > 0)
-                    return elements;
+                    return;
                 break;
             case ID_LFE:
                 hDecoder->has_lfe++;
-                elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                    hInfo, ld, spec_coef, id_syn_ele);
+                decode_sce_lfe(hDecoder, hInfo, ld, id_syn_ele);
                 if (hInfo->error > 0)
-                    return elements;
+                    return;
                 break;
             case ID_CCE: /* not implemented yet, but skip the bits */
+#ifdef COUPLING_DEC
                 hInfo->error = coupling_channel_element(hDecoder, ld);
+#else
+                hInfo->error = 6;
+#endif
                 if (hInfo->error > 0)
-                    return elements;
+                    return;
                 break;
             case ID_DSE:
                 data_stream_element(hDecoder, ld);
                 break;
             case ID_PCE:
-                if ((hInfo->error = program_config_element(pce, ld)) > 0)
-                    return elements;
-                hDecoder->pce_set = 1;
+                /* 14496-4: 5.6.4.1.2.1.3: */
+                /* program_configuration_element()'s in access units shall be ignored */
+                program_config_element(pce, ld);
+                //if ((hInfo->error = program_config_element(pce, ld)) > 0)
+                //    return;
+                //hDecoder->pce_set = 1;
                 break;
             case ID_FIL:
                 /* one sbr_info describes a channel_element not a channel! */
+                /* if we encounter SBR data here: error */
+                /* SBR data will be read directly in the SCE/LFE/CPE element */
                 if ((hInfo->error = fill_element(hDecoder, ld, drc
 #ifdef SBR_DEC
-                    , (ch_ele-1)
+                    , INVALID_SBR_ELEMENT
 #endif
                     )) > 0)
-                    return elements;
-#ifdef SBR_DEC
-                if (hDecoder->sbr_used[ch_ele-1])
-                {
-                    hDecoder->sbr_present_flag = 1;
-                    hDecoder->sbr[ch_ele-1]->sample_rate = get_sample_rate(hDecoder->sf_index);
-                    hDecoder->sbr[ch_ele-1]->sample_rate *= 2;
-                }
-#endif
+                    return;
                 break;
             }
         }
@@ -435,74 +483,55 @@
         switch (hDecoder->channelConfiguration)
         {
         case 1:
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
         case 2:
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
         case 3:
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
         case 4:
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
         case 5:
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
         case 6:
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_LFE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_LFE);
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
-        case 7:
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_SCE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_cpe(hDecoder,
-                hInfo, ld, spec_coef, ID_CPE);
-            elements[ch_ele++] = decode_sce_lfe(hDecoder,
-                hInfo, ld, spec_coef, ID_LFE);
+        case 7: /* 8 channels */
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE);
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            decode_cpe(hDecoder, hInfo, ld, ID_CPE);
+            decode_sce_lfe(hDecoder, hInfo, ld, ID_LFE);
             if (hInfo->error > 0)
-                return elements;
+                return;
             break;
         default:
             hInfo->error = 7;
-            return elements;
+            return;
         }
 #if 0
         cnt = bits_to_decode() / 8;
@@ -522,98 +551,76 @@
         faad_byte_align(ld);
     }
 
-    return elements;
+    return;
 }
 
 /* Table 4.4.4 and */
 /* Table 4.4.9 */
-static uint8_t single_lfe_channel_element(faacDecHandle hDecoder,
-                                          element *sce, bitfile *ld,
-                                          real_t *spec_coef)
+static uint8_t single_lfe_channel_element(faacDecHandle hDecoder, bitfile *ld,
+                                          uint8_t channel, uint8_t *tag)
 {
     uint8_t retval = 0;
-    ic_stream *ics = &(sce->ics1);
-    int16_t spec_data[1024];
-#ifdef DRM
-    uint8_t result;
+    element sce = {0};
+    ic_stream *ics = &(sce.ics1);
+    ALIGN int16_t spec_data[1024] = {0};
 
-    if (hDecoder->object_type != DRM_ER_LC)
-#endif
-    sce->element_instance_tag = (uint8_t)faad_getbits(ld, LEN_TAG
+    sce.element_instance_tag = (uint8_t)faad_getbits(ld, LEN_TAG
         DEBUGVAR(1,38,"single_lfe_channel_element(): element_instance_tag"));
 
-#ifdef DRM
-    if (hDecoder->object_type == DRM_ER_LC)
-    {
-        individual_channel_stream(hDecoder, sce, ld, ics, 0, spec_data);
+    *tag = sce.element_instance_tag;
+    sce.channel = channel;
+    sce.paired_channel = -1;
 
-        if (ics->tns_data_present)
-            tns_data(ics, &(ics->tns), ld);
-
-        if ((result = faad_check_CRC( ld, faad_get_processed_bits(ld) - 8 )) > 0)
-            return result;
-
-        /* error resilient spectral data decoding */
-        if ((result = reordered_spectral_data(hDecoder, ics, ld, spec_data)) > 0)
-            return result;
+    retval = individual_channel_stream(hDecoder, &sce, ld, ics, 0, spec_data);
+    if (retval > 0)
+        return retval;
 
-        /* pulse coding reconstruction */
-        if (ics->pulse_data_present)
+#ifdef SBR_DEC
+    /* check if next bitstream element is a fill element */
+    /* if so, read it now so SBR decoding can be done in case of a file with SBR */
+    if (faad_showbits(ld, LEN_SE_ID) == ID_FIL)
+    {
+        faad_flushbits(ld, LEN_SE_ID);
+
+        /* one sbr_info describes a channel_element not a channel! */
+        if ((retval = fill_element(hDecoder, ld, hDecoder->drc, hDecoder->fr_ch_ele)) > 0)
         {
-            if (ics->window_sequence != EIGHT_SHORT_SEQUENCE)
-            {
-                if ((result = pulse_decode(ics, spec_data, hDecoder->frameLength)) > 0)
-                    return result;
-            } else {
-                return 2; /* pulse coding not allowed for short blocks */
-            }
+            return retval;
         }
-    } else
+    }
 #endif
-    {
-        retval = individual_channel_stream(hDecoder, sce, ld, ics, 0, spec_data);
-        if (retval > 0)
-            return retval;
-    }
-
 
     /* noiseless coding is done, spectral reconstruction is done now */
-
-    /* inverse quantization */
-    inverse_quantization(spec_coef, spec_data, hDecoder->frameLength);
-
-    /* apply scalefactors */
-    apply_scalefactors(hDecoder, ics, spec_coef, hDecoder->frameLength);
-
-    /* deinterleave short block grouping */
-    if (ics->window_sequence == EIGHT_SHORT_SEQUENCE)
-        quant_to_spec(ics, spec_coef, hDecoder->frameLength);
+    retval = reconstruct_single_channel(hDecoder, ics, &sce, spec_data);
+    if (retval > 0)
+        return retval;
 
     return 0;
 }
 
 /* Table 4.4.5 */
-static uint8_t channel_pair_element(faacDecHandle hDecoder, element *cpe,
-                                    bitfile *ld,
-                                    real_t *spec_coef1, real_t *spec_coef2)
+static uint8_t channel_pair_element(faacDecHandle hDecoder, bitfile *ld,
+                                    uint8_t channels, uint8_t *tag)
 {
+    ALIGN int16_t spec_data1[1024] = {0};
+    ALIGN int16_t spec_data2[1024] = {0};
+    element cpe = {0};
+    ic_stream *ics1 = &(cpe.ics1);
+    ic_stream *ics2 = &(cpe.ics2);
     uint8_t result;
-    ic_stream *ics1 = &(cpe->ics1);
-    ic_stream *ics2 = &(cpe->ics2);
-    int16_t spec_data1[1024];
-    int16_t spec_data2[1024];
+
+    cpe.channel        = channels;
+    cpe.paired_channel = channels+1;
 
-#ifdef DRM
-    if (hDecoder->object_type != DRM_ER_LC)
-#endif
-    cpe->element_instance_tag = (uint8_t)faad_getbits(ld, LEN_TAG
+    cpe.element_instance_tag = (uint8_t)faad_getbits(ld, LEN_TAG
         DEBUGVAR(1,39,"channel_pair_element(): element_instance_tag"));
+    *tag = cpe.element_instance_tag;
 
-    if ((cpe->common_window = faad_get1bit(ld
+    if ((cpe.common_window = faad_get1bit(ld
         DEBUGVAR(1,40,"channel_pair_element(): common_window"))) & 1)
     {
         /* both channels have common ics information */
-        if ((result = ics_info(hDecoder, ics1, ld, cpe->common_window)) > 0)
+        if ((result = ics_info(hDecoder, ics1, ld, cpe.common_window)) > 0)
             return result;
 
         ics1->ms_mask_present = (uint8_t)faad_getbits(ld, 2
@@ -637,7 +644,10 @@
             if ((ics1->ltp.data_present = faad_get1bit(ld
                 DEBUGVAR(1,50,"channel_pair_element(): ltp.data_present"))) & 1)
             {
-                ltp_data(hDecoder, ics1, &(ics1->ltp), ld);
+                if ((result = ltp_data(hDecoder, ics1, &(ics1->ltp), ld)) > 0)
+                {
+                    return result;
+                }
             }
         }
 #endif
@@ -647,106 +657,58 @@
         ics1->ms_mask_present = 0;
     }
 
-    if ((result = individual_channel_stream(hDecoder, cpe, ld, ics1,
+    if ((result = individual_channel_stream(hDecoder, &cpe, ld, ics1,
         0, spec_data1)) > 0)
     {
         return result;
     }
 
 #ifdef ERROR_RESILIENCE
-    if (cpe->common_window && (hDecoder->object_type >= ER_OBJECT_START) &&
+    if (cpe.common_window && (hDecoder->object_type >= ER_OBJECT_START) &&
         (ics1->predictor_data_present))
     {
         if ((ics1->ltp2.data_present = faad_get1bit(ld
             DEBUGVAR(1,50,"channel_pair_element(): ltp.data_present"))) & 1)
         {
-            ltp_data(hDecoder, ics1, &(ics1->ltp2), ld);
+            if ((result = ltp_data(hDecoder, ics1, &(ics1->ltp2), ld)) > 0)
+            {
+                return result;
+            }
         }
     }
 #endif
 
-    if ((result = individual_channel_stream(hDecoder, cpe, ld, ics2,
+    if ((result = individual_channel_stream(hDecoder, &cpe, ld, ics2,
         0, spec_data2)) > 0)
     {
         return result;
     }
 
-#ifdef DRM
-    if (hDecoder->object_type == DRM_ER_LC)
+#ifdef SBR_DEC
+    /* check if next bitstream element is a fill element */
+    /* if so, read it now so SBR decoding can be done in case of a file with SBR */
+    if (faad_showbits(ld, LEN_SE_ID) == ID_FIL)
     {
-        if (ics1->tns_data_present)
-            tns_data(ics1, &(ics1->tns), ld);
+        faad_flushbits(ld, LEN_SE_ID);
 
-        if (ics1->tns_data_present)
-            tns_data(ics2, &(ics2->tns), ld);
-
-        if ((result = faad_check_CRC( ld, faad_get_processed_bits(ld) - 8 )) > 0)
-            return result;
-
-        /* error resilient spectral data decoding */
-        if ((result = reordered_spectral_data(hDecoder, ics1, ld, spec_data1)) > 0)
-            return result;
-        if ((result = reordered_spectral_data(hDecoder, ics2, ld, spec_data2)) > 0)
+        /* one sbr_info describes a channel_element not a channel! */
+        if ((result = fill_element(hDecoder, ld, hDecoder->drc, hDecoder->fr_ch_ele)) > 0)
+        {
             return result;
-        /* pulse coding reconstruction */
-        if (ics1->pulse_data_present)
-        {
-            if (ics1->window_sequence != EIGHT_SHORT_SEQUENCE)
-            {
-                if ((result = pulse_decode(ics1, spec_data1, hDecoder->frameLength)) > 0)
-                    return result;
-            } else {
-                return 2; /* pulse coding not allowed for short blocks */
-            }
-        }
-        if (ics2->pulse_data_present)
-        {
-            if (ics2->window_sequence != EIGHT_SHORT_SEQUENCE)
-            {
-                if ((result = pulse_decode(ics2, spec_data2, hDecoder->frameLength)) > 0)
-                    return result;
-            } else {
-                return 2; /* pulse coding not allowed for short blocks */
-            }
         }
     }
 #endif
 
     /* noiseless coding is done, spectral reconstruction is done now */
-
-    /* inverse quantization */
-    inverse_quantization(spec_coef1, spec_data1, hDecoder->frameLength);
-    inverse_quantization(spec_coef2, spec_data2, hDecoder->frameLength);
-
-    /* apply scalefactors */
-    apply_scalefactors(hDecoder, ics1, spec_coef1, hDecoder->frameLength);
-    apply_scalefactors(hDecoder, ics2, spec_coef2, hDecoder->frameLength);
-
-    /* deinterleave short block grouping */
-    if (ics1->window_sequence == EIGHT_SHORT_SEQUENCE)
-        quant_to_spec(ics1, spec_coef1, hDecoder->frameLength);
-    if (ics2->window_sequence == EIGHT_SHORT_SEQUENCE)
-        quant_to_spec(ics2, spec_coef2, hDecoder->frameLength);
+    if ((result = reconstruct_channel_pair(hDecoder, ics1, ics2, &cpe,
+        spec_data1, spec_data2)) > 0)
+    {
+        return result;
+    }
 
     return 0;
 }
 
-static uint8_t pred_sfb_max[] =
-{
-    33,     /* 96000 */
-    33,     /* 88200 */
-    38,     /* 64000 */
-    40,     /* 48000 */
-    40,     /* 44100 */
-    40,     /* 32000 */
-    41,     /* 24000 */
-    41,     /* 22050 */
-    37,     /* 16000 */
-    37,     /* 12000 */
-    37,     /* 11025 */
-    34      /* 8000  */
-};
-
 /* Table 4.4.6 */
 static uint8_t ics_info(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld,
                         uint8_t common_window)
@@ -789,7 +751,7 @@
             {
                 uint8_t sfb;
 
-                ics->pred.limit = min(ics->max_sfb, pred_sfb_max[hDecoder->sf_index]);
+                ics->pred.limit = min(ics->max_sfb, max_pred_sfb(hDecoder->sf_index));
 
                 if ((ics->pred.predictor_reset = faad_get1bit(ld
                     DEBUGVAR(1,53,"ics_info(): pred.predictor_reset"))) & 1)
@@ -811,14 +773,20 @@
                     if ((ics->ltp.data_present = faad_get1bit(ld
                         DEBUGVAR(1,50,"ics_info(): ltp.data_present"))) & 1)
                     {
-                        ltp_data(hDecoder, ics, &(ics->ltp), ld);
+                        if ((retval = ltp_data(hDecoder, ics, &(ics->ltp), ld)) > 0)
+                        {
+                            return retval;
+                        }
                     }
                     if (common_window)
                     {
                         if ((ics->ltp2.data_present = faad_get1bit(ld
                             DEBUGVAR(1,51,"ics_info(): ltp2.data_present"))) & 1)
                         {
-                            ltp_data(hDecoder, ics, &(ics->ltp2), ld);
+                            if ((retval = ltp_data(hDecoder, ics, &(ics->ltp2), ld)) > 0)
+                            {
+                                return retval;
+                            }
                         }
                     }
                 }
@@ -865,6 +833,7 @@
     return 0;
 }
 
+#ifdef COUPLING_DEC
 /* Table 4.4.8: Currently just for skipping the bits... */
 static uint8_t coupling_channel_element(faacDecHandle hDecoder, bitfile *ld)
 {
@@ -873,13 +842,10 @@
     uint8_t num_gain_element_lists = 0;
     uint8_t num_coupled_elements = 0;
 
-    element el_empty;
-    ic_stream ics_empty;
+    element el_empty = {0};
+    ic_stream ics_empty = {0};
     int16_t sh_data[1024];
 
-    memset(&el_empty, 0, sizeof(element));
-    memset(&ics_empty, 0, sizeof(ic_stream));
-
     c = faad_getbits(ld, LEN_TAG
         DEBUGVAR(1,900,"coupling_channel_element(): element_instance_tag"));
 
@@ -955,6 +921,7 @@
 
     return 0;
 }
+#endif
 
 /* Table 4.4.10 */
 static uint16_t data_stream_element(faacDecHandle hDecoder, bitfile *ld)
@@ -978,7 +945,7 @@
 
     for (i = 0; i < count; i++)
     {
-        uint8_t data = faad_getbits(ld, LEN_BYTE
+        faad_getbits(ld, LEN_BYTE
             DEBUGVAR(1,64,"data_stream_element(): data_stream_byte"));
     }
 
@@ -1008,28 +975,35 @@
     if (count > 0)
     {
 #ifdef SBR_DEC
-        hDecoder->sbr_used[sbr_ele] = 0;
         bs_extension_type = (uint8_t)faad_showbits(ld, 4);
 
         if ((bs_extension_type == EXT_SBR_DATA) ||
             (bs_extension_type == EXT_SBR_DATA_CRC))
         {
-            hDecoder->sbr_used[sbr_ele] = 1;
+            if (sbr_ele == INVALID_SBR_ELEMENT)
+                return 24;
 
             if (!hDecoder->sbr[sbr_ele])
             {
-                hDecoder->sbr[sbr_ele] = sbrDecodeInit(hDecoder->frameLength
+                hDecoder->sbr[sbr_ele] = sbrDecodeInit(hDecoder->frameLength,
+                    hDecoder->element_id[sbr_ele], 2*get_sample_rate(hDecoder->sf_index)
 #ifdef DRM
                     , 0
 #endif
                     );
             }
 
-            /* read in all the SBR data for processing later on */
-            hDecoder->sbr[sbr_ele]->data = (uint8_t*)faad_getbitbuffer(ld, count*8);
-            hDecoder->sbr[sbr_ele]->data_size = count;
+            hDecoder->sbr_present_flag = 1;
+
+            /* parse the SBR data */
+            hDecoder->sbr[sbr_ele]->ret = sbr_extension_data(ld, hDecoder->sbr[sbr_ele], count);
+#if (defined(PS_DEC) || defined(DRM_PS))
+            if (hDecoder->sbr[sbr_ele]->ps_used)
+            {
+                hDecoder->ps_used[sbr_ele] = 1;
+            }
+#endif
         } else {
-            hDecoder->sbr_used[sbr_ele] = 0;
 #endif
             while (count > 0)
             {
@@ -1139,6 +1113,261 @@
 }
 #endif
 
+#ifdef SCALABLE_DEC
+/* Table 4.4.13 ASME */
+void aac_scalable_main_element(faacDecHandle hDecoder, faacDecFrameInfo *hInfo,
+                               bitfile *ld, program_config *pce, drc_info *drc)
+{
+    uint8_t retval = 0;
+    uint8_t channels = hDecoder->fr_channels = 0;
+    uint8_t ch;
+    uint8_t this_layer_stereo = (hDecoder->channelConfiguration > 1) ? 1 : 0;
+    element cpe = {0};
+    ic_stream *ics1 = &(cpe.ics1);
+    ic_stream *ics2 = &(cpe.ics2);
+    int16_t *spec_data;
+    ALIGN int16_t spec_data1[1024] = {0};
+    ALIGN int16_t spec_data2[1024] = {0};
+
+    hDecoder->fr_ch_ele = 0;
+
+    hInfo->error = aac_scalable_main_header(hDecoder, ics1, ics2, ld, this_layer_stereo);
+    if (hInfo->error > 0)
+        return;
+
+    cpe.common_window = 1;
+    if (this_layer_stereo)
+        cpe.ele_id = ID_CPE;
+    else
+        cpe.ele_id = ID_SCE;
+
+    hDecoder->element_output_channels[hDecoder->fr_ch_ele] = (this_layer_stereo ? 2 : 0);
+
+    for (ch = 0; ch < (this_layer_stereo ? 2 : 1); ch++)
+    {
+        ic_stream *ics;
+        if (ch == 0)
+        {
+            ics = ics1;
+            spec_data = spec_data1;
+        } else {
+            ics = ics2;
+            spec_data = spec_data2;
+        }
+
+        hInfo->error = individual_channel_stream(hDecoder, &cpe, ld, ics, 1, spec_data);
+        if (hInfo->error > 0)
+            return;
+    }
+
+#ifdef DRM
+#ifdef SBR_DEC
+    /* In case of DRM we need to read the SBR info before channel reconstruction */
+    if ((hDecoder->sbr_present_flag == 1) && (hDecoder->object_type == DRM_ER_LC))
+    {
+        bitfile ld_sbr = {0};
+        uint32_t i;
+        uint16_t count = 0;
+        uint8_t *revbuffer;
+        uint8_t *prevbufstart;
+        uint8_t *pbufend;
+
+        /* all forward bitreading should be finished at this point */
+        uint32_t bitsconsumed = faad_get_processed_bits(ld);
+        uint32_t buffer_size = faad_origbitbuffer_size(ld);
+        uint8_t *buffer = (uint8_t*)faad_origbitbuffer(ld);
+
+        if (bitsconsumed + 8 > buffer_size*8)
+        {
+            hInfo->error = 14;
+            return;
+        }
+
+        if (!hDecoder->sbr[0])
+        {
+            hDecoder->sbr[0] = sbrDecodeInit(hDecoder->frameLength, cpe.ele_id,
+                2*get_sample_rate(hDecoder->sf_index), 1);
+        }
+
+        /* Reverse bit reading of SBR data in DRM audio frame */
+        revbuffer = (uint8_t*)faad_malloc(buffer_size*sizeof(uint8_t));
+        prevbufstart = revbuffer;
+        pbufend = &buffer[buffer_size - 1];
+        for (i = 0; i < buffer_size; i++)
+            *prevbufstart++ = tabFlipbits[*pbufend--];
+
+        /* Set SBR data */
+        /* consider 8 bits from AAC-CRC */
+        count = (uint16_t)bit2byte(buffer_size*8 - bitsconsumed);
+        faad_initbits(&ld_sbr, revbuffer, count);
+
+        hDecoder->sbr[0]->lcstereo_flag = hDecoder->lcstereo_flag;
+
+        hDecoder->sbr[0]->sample_rate = get_sample_rate(hDecoder->sf_index);
+        hDecoder->sbr[0]->sample_rate *= 2;
+
+        faad_getbits(&ld_sbr, 8); /* Skip 8-bit CRC */
+
+        hDecoder->sbr[0]->ret = sbr_extension_data(&ld_sbr, hDecoder->sbr[0], count);
+#if (defined(PS_DEC) || defined(DRM_PS))
+        if (hDecoder->sbr[0]->ps_used)
+        {
+            hDecoder->ps_used[0] = 1;
+        }
+#endif
+
+        /* check CRC */
+        /* no need to check it if there was already an error */
+        if (hDecoder->sbr[0]->ret == 0)
+            hDecoder->sbr[0]->ret = faad_check_CRC(&ld_sbr, faad_get_processed_bits(&ld_sbr) - 8);
+
+        faad_endbits(&ld_sbr);
+
+        if (revbuffer)
+            faad_free(revbuffer);
+    }
+#endif
+#endif
+
+    if (this_layer_stereo)
+    {
+        hInfo->error = reconstruct_channel_pair(hDecoder, ics1, ics2, &cpe, spec_data1, spec_data2);
+        if (hInfo->error > 0)
+            return;
+    } else {
+        hInfo->error = reconstruct_single_channel(hDecoder, ics1, &cpe, spec_data1);
+        if (hInfo->error > 0)
+            return;
+    }
+
+    /* map output channels position to internal data channels */
+    if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 2)
+    {
+        /* this might be faulty when pce_set is true */
+        hDecoder->internal_channel[channels] = channels;
+        hDecoder->internal_channel[channels+1] = channels+1;
+    } else {
+        hDecoder->internal_channel[channels] = channels;
+    }
+
+    hDecoder->element_id[hDecoder->fr_ch_ele] = cpe.ele_id;
+
+    hDecoder->fr_channels += hDecoder->element_output_channels[hDecoder->fr_ch_ele];
+    hDecoder->fr_ch_ele++;
+
+    return;
+}
+
+/* Table 4.4.15 */
+static int8_t aac_scalable_main_header(faacDecHandle hDecoder, ic_stream *ics1, ic_stream *ics2,
+                                       bitfile *ld, uint8_t this_layer_stereo)
+{
+    uint8_t retval = 0;
+    uint8_t ch;
+    ic_stream *ics;
+
+    /* ics1->ics_reserved_bit = */ faad_get1bit(ld
+        DEBUGVAR(1,300,"aac_scalable_main_header(): ics_reserved_bits"));
+    ics1->window_sequence = (uint8_t)faad_getbits(ld, 2
+        DEBUGVAR(1,301,"aac_scalable_main_header(): window_sequence"));
+    ics1->window_shape = faad_get1bit(ld
+        DEBUGVAR(1,302,"aac_scalable_main_header(): window_shape"));
+
+    if (ics1->window_sequence == EIGHT_SHORT_SEQUENCE)
+    {
+        ics1->max_sfb = (uint8_t)faad_getbits(ld, 4
+            DEBUGVAR(1,303,"aac_scalable_main_header(): max_sfb (short)"));
+        ics1->scale_factor_grouping = (uint8_t)faad_getbits(ld, 7
+            DEBUGVAR(1,304,"aac_scalable_main_header(): scale_factor_grouping"));
+    } else {
+        ics1->max_sfb = (uint8_t)faad_getbits(ld, 6
+            DEBUGVAR(1,305,"aac_scalable_main_header(): max_sfb (long)"));
+    }
+
+    /* get the grouping information */
+    if ((retval = window_grouping_info(hDecoder, ics1)) > 0)
+        return retval;
+
+    /* should be an error */
+    /* check the range of max_sfb */
+    if (ics1->max_sfb > ics1->num_swb)
+        return 16;
+
+    if (this_layer_stereo)
+    {
+        ics1->ms_mask_present = (uint8_t)faad_getbits(ld, 2
+            DEBUGVAR(1,306,"aac_scalable_main_header(): ms_mask_present"));
+        if (ics1->ms_mask_present == 1)
+        {
+            uint8_t g, sfb;
+            for (g = 0; g < ics1->num_window_groups; g++)
+            {
+                for (sfb = 0; sfb < ics1->max_sfb; sfb++)
+                {
+                    ics1->ms_used[g][sfb] = faad_get1bit(ld
+                        DEBUGVAR(1,307,"aac_scalable_main_header(): faad_get1bit"));
+                }
+            }
+        }
+
+        memcpy(ics2, ics1, sizeof(ic_stream));
+    } else {
+        ics1->ms_mask_present = 0;
+    }
+
+    if (0)
+    {
+        faad_get1bit(ld
+            DEBUGVAR(1,308,"aac_scalable_main_header(): tns_channel_mono_layer"));
+    }
+
+    for (ch = 0; ch < (this_layer_stereo ? 2 : 1); ch++)
+    {
+        if (ch == 0)
+            ics = ics1;
+        else
+            ics = ics2;
+
+        if ( 1 /*!tvq_layer_pesent || (tns_aac_tvq_en[ch] == 1)*/)
+        {
+            if ((ics->tns_data_present = faad_get1bit(ld
+                DEBUGVAR(1,309,"aac_scalable_main_header(): tns_data_present"))) & 1)
+            {
+#ifdef DRM
+                /* different order of data units in DRM */
+                if (hDecoder->object_type != DRM_ER_LC)
+#endif
+                {
+                    tns_data(ics, &(ics->tns), ld);
+                }
+            }
+        }
+#if 0
+        if (0 /*core_flag || tvq_layer_pesent*/)
+        {
+            if ((ch==0) || ((ch==1) && (core_stereo || tvq_stereo))
+                diff_control_data();
+            if (mono_stereo_flag)
+                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 ((retval = ltp_data(hDecoder, ics, &(ics->ltp), ld)) > 0)
+                {
+                    return retval;
+                }
+            }
+#if 0
+        }
+#endif
+    }
+
+    return 0;
+}
+#endif
+
 /* Table 4.4.24 */
 static uint8_t individual_channel_stream(faacDecHandle hDecoder, element *ele,
                                          bitfile *ld, ic_stream *ics, uint8_t scal_flag,
@@ -1229,17 +1458,19 @@
             return result;
     }
 
-#ifdef DRM
-    if (hDecoder->object_type == DRM_ER_LC)
-        return 0;
-#endif
-
     if (hDecoder->object_type >= ER_OBJECT_START) 
     {
         if (ics->tns_data_present)
             tns_data(ics, &(ics->tns), ld);
     }
 
+#ifdef DRM
+    /* CRC check */
+    if (hDecoder->object_type == DRM_ER_LC)
+        if ((result = faad_check_CRC(ld, faad_get_processed_bits(ld) - 8)) > 0)
+            return result;
+#endif
+
     if (hDecoder->aacSpectralDataResilienceFlag)
     {
         /* error resilient spectral data decoding */
@@ -1416,8 +1647,6 @@
 
                 /* decode intensity position */
                 t = huffman_scale_factor(ld);
-                if (t < 0)
-                    return 9;
                 is_position += (t - 60);
                 ics->scale_factors[g][sfb] = is_position;
 
@@ -1432,8 +1661,6 @@
                         DEBUGVAR(1,73,"scale_factor_data(): first noise")) - 256;
                 } else {
                     t = huffman_scale_factor(ld);
-                    if (t < 0)
-                        return 9;
                     t -= 60;
                 }
                 noise_energy += t;
@@ -1442,12 +1669,14 @@
                 break;
             default: /* spectral books */
 
+                /* ics->scale_factors[g][sfb] must be between 0 and 255 */
+
+                ics->scale_factors[g][sfb] = 0;
+
                 /* decode scale factor */
                 t = huffman_scale_factor(ld);
-                if (t < 0)
-                    return 9;
                 scale_factor += (t - 60);
-                if (scale_factor < 0)
+                if (scale_factor < 0 || scale_factor > 255)
                     return 4;
                 ics->scale_factors[g][sfb] = scale_factor;
 
@@ -1462,20 +1691,32 @@
 /* Table 4.4.26 */
 static uint8_t scale_factor_data(faacDecHandle hDecoder, ic_stream *ics, bitfile *ld)
 {
+    uint8_t ret = 0;
+#ifdef PROFILE
+    int64_t count = faad_get_ts();
+#endif
+
 #ifdef ERROR_RESILIENCE
     if (!hDecoder->aacScalefactorDataResilienceFlag)
     {
 #endif
-        return decode_scale_factors(ics, ld);
+        ret = decode_scale_factors(ics, ld);
 #ifdef ERROR_RESILIENCE
     } else {
         /* In ER AAC the parameters for RVLC are seperated from the actual
            data that holds the scale_factors.
            Strangely enough, 2 parameters for HCR are put inbetween them.
         */
-        return rvlc_scale_factor_data(ics, ld);
+        ret = rvlc_scale_factor_data(ics, ld);
     }
 #endif
+
+#ifdef PROFILE
+    count = faad_get_ts() - count;
+    hDecoder->scalefac_cycles += count;
+#endif
+
+    return ret;
 }
 
 /* Table 4.4.27 */
@@ -1535,10 +1776,12 @@
 
 #ifdef LTP_DEC
 /* Table 4.4.28 */
-static void ltp_data(faacDecHandle hDecoder, ic_stream *ics, ltp_info *ltp, bitfile *ld)
+static uint8_t ltp_data(faacDecHandle hDecoder, ic_stream *ics, ltp_info *ltp, bitfile *ld)
 {
     uint8_t sfb, w;
 
+    ltp->lag = 0;
+
 #ifdef LD_DEC
     if (hDecoder->object_type == LD)
     {
@@ -1557,6 +1800,11 @@
 #ifdef LD_DEC
     }
 #endif
+
+    /* Check length of lag */
+    if (ltp->lag > (hDecoder->frameLength << 1))
+        return 18;
+
     ltp->coef = (uint8_t)faad_getbits(ld, 3
         DEBUGVAR(1,82,"ltp_data(): coef"));
 
@@ -1585,6 +1833,8 @@
                 DEBUGVAR(1,86,"ltp_data(): long_used"));
         }
     }
+
+    return 0;
 }
 #endif
 
@@ -1594,15 +1844,15 @@
 {
     int8_t i;
     uint8_t g;
-    int16_t *sp;
-    uint16_t k, p = 0;
+    uint16_t inc, k, p = 0;
     uint8_t groups = 0;
     uint8_t sect_cb;
     uint8_t result;
     uint16_t nshort = hDecoder->frameLength/8;
 
-    sp = spectral_data;
-    memset(sp, 0, hDecoder->frameLength*sizeof(int16_t));
+#ifdef PROFILE
+    int64_t count = faad_get_ts();
+#endif
 
     for(g = 0; g < ics->num_window_groups; g++)
     {
@@ -1612,6 +1862,8 @@
         {
             sect_cb = ics->sect_cb[g][i];
 
+            inc = (sect_cb >= FIRST_PAIR_HCB) ? 2 : 4;
+
             switch (sect_cb)
             {
             case ZERO_HCB:
@@ -1623,18 +1875,11 @@
                 break;
             default:
                 for (k = ics->sect_sfb_offset[g][ics->sect_start[g][i]];
-                     k < ics->sect_sfb_offset[g][ics->sect_end[g][i]]; k += 4)
+                     k < ics->sect_sfb_offset[g][ics->sect_end[g][i]]; k += inc)
                 {
-                    sp = spectral_data + p;
-
-                        if ((result = huffman_spectral_data(sect_cb, ld, sp)) > 0)
-                            return result;
-                    if (sect_cb >= FIRST_PAIR_HCB)
-                    {
-                        if ((result = huffman_spectral_data(sect_cb, ld, sp+2)) > 0)
-                            return result;
-                    }
-                    p += 4;
+                    if ((result = huffman_spectral_data(sect_cb, ld, &spectral_data[p])) > 0)
+                        return result;
+                    p += inc;
                 }
                 break;
             }
@@ -1642,6 +1887,11 @@
         groups += ics->window_group_length[g];
     }
 
+#ifdef PROFILE
+    count = faad_get_ts() - count;
+    hDecoder->spectral_cycles += count;
+#endif
+
     return 0;
 }
 
@@ -1671,7 +1921,7 @@
         }
         return count;
     case EXT_DATA_ELEMENT:
-        data_element_version = faad_getbits(ld, 4
+        data_element_version = (uint8_t)faad_getbits(ld, 4
             DEBUGVAR(1,400,"extension_payload(): data_element_version"));
         switch (data_element_version)
         {
@@ -1679,7 +1929,7 @@
             loopCounter = 0;
             dataElementLength = 0;
             do {
-                dataElementLengthPart = faad_getbits(ld, 8
+                dataElementLengthPart = (uint8_t)faad_getbits(ld, 8
                     DEBUGVAR(1,401,"extension_payload(): dataElementLengthPart"));
                 dataElementLength += dataElementLengthPart;
                 loopCounter++;
@@ -1909,11 +2159,11 @@
     if (adts->old_format == 1)
     {
         /* Removed in corrigendum 14496-3:2002 */
-    if (adts->id == 0)
-    {
-        adts->emphasis = (uint8_t)faad_getbits(ld, 2
-            DEBUGVAR(1,128,"adts_fixed_header(): emphasis"));
-    }
+        if (adts->id == 0)
+        {
+            adts->emphasis = (uint8_t)faad_getbits(ld, 2
+                DEBUGVAR(1,128,"adts_fixed_header(): emphasis"));
+        }
     }
 
     return 0;