/*  Copyright (c) MediaArea.net SARL. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license that can
 *  be found in the License.html file in the root of the source tree.
 */
 
//---------------------------------------------------------------------------
// Pre-compilation
#include "MediaInfo/PreComp.h"
#ifdef __BORLANDC__
    #pragma hdrstop
#endif
//---------------------------------------------------------------------------
 
//---------------------------------------------------------------------------
#include "MediaInfo/Setup.h"
//---------------------------------------------------------------------------
 
//---------------------------------------------------------------------------
#if defined(MEDIAINFO_AAC_YES)
//---------------------------------------------------------------------------
 
//---------------------------------------------------------------------------
#include "MediaInfo/Audio/File_Aac.h"
#include "MediaInfo/Audio/File_Aac_GeneralAudio.h"
using namespace std;
//---------------------------------------------------------------------------
 
namespace MediaInfoLib
{
 
//***************************************************************************
// Infos
//***************************************************************************
 
//---------------------------------------------------------------------------
extern const int32u Aac_sampling_frequency[];
extern const char* Aac_audioObjectType(int8u audioObjectType);
extern const char* Aac_Format_Profile(int8u ID);
 
//---------------------------------------------------------------------------
static const char* Aac_id_syn_ele[8]=
{
    "SCE - single_channel_element",
    "CPE - channel_pair_element",
    "CCE - coupling_channel_element",
    "LFE - lfe_channel_element",
    "DSE - data_stream_element",
    "PCE - program_config_element",
    "FIL - fill_element",
    "END - End"
};
 
//---------------------------------------------------------------------------
static const char* Aac_window_sequence[4]=
{
    "ONLY_LONG_SEQUENCE",
    "LONG_START_SEQUENCE",
    "EIGHT_SHORT_SEQUENCE",
    "LONG_STOP_SEQUENCE"
};
 
//***************************************************************************
// Elements - Decoder configuration
//***************************************************************************
 
//---------------------------------------------------------------------------
void File_Aac::GASpecificConfig ()
{
    //Parsing
    Element_Begin1("GASpecificConfig");
    bool frameLengthFlag, dependsOnCoreCoder, extensionFlag;
    Get_SB (   frameLengthFlag,                                 "frameLengthFlag");
    frame_length=frameLengthFlag==0?1024:960; Param_Info2(frame_length, " bytes");
    Get_SB (   dependsOnCoreCoder,                              "dependsOnCoreCoder");
    if (dependsOnCoreCoder)
        Skip_S2(14,                                             "coreCoderDelay");
    Get_SB (   extensionFlag,                                   "extensionFlag");
    if (channelConfiguration==0)
        program_config_element();
    if (audioObjectType==06 || audioObjectType==20)
        Skip_S1(3,                                              "layerNr");
    if (extensionFlag)
    {
        bool extensionFlag3;
        if (audioObjectType==22)
        {
            Skip_S1( 5,                                         "numOfSubFrame");
            Skip_S2(11,                                         "layer_length");
        }
        if (audioObjectType==17
         || audioObjectType==19
         || audioObjectType==20
         || audioObjectType==23)
        {
            Skip_SB(                                            "aacSectionDataResilienceFlag");
            Skip_SB(                                            "aacScalefactorDataResilienceFlag");
            Skip_SB(                                            "aacSpectralDataResilienceFlag");
        }
        Get_SB (   extensionFlag3,                              "extensionFlag3");
        if (extensionFlag3)
        {
            Skip_BS(Data_BS_Remain(),                           "Not implemented");
        }
    }
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::program_config_element()
{
    Element_Begin1("program_config_element");
    Ztring comment_field_data;
    int8u Channels=0, Channels_Front=0, Channels_Side=0, Channels_Back=0, Channels_LFE=0;
    int8u num_front_channel_elements, num_side_channel_elements, num_back_channel_elements, num_lfe_channel_elements, num_assoc_data_elements, num_valid_cc_elements, comment_field_bytes;
    int8u audioObjectType_Temp, sampling_frequency_index_Temp;
    Skip_S1(4,                                                  "element_instance_tag");
    Get_S1 (2, audioObjectType_Temp,                            "object_type"); audioObjectType_Temp++; Param_Info1(Aac_audioObjectType(audioObjectType_Temp));
    Get_S1 (4, sampling_frequency_index_Temp,                   "sampling_frequency_index"); Param_Info1(Aac_sampling_frequency[sampling_frequency_index_Temp]);
    Get_S1 (4, num_front_channel_elements,                      "num_front_channel_elements");
    Get_S1 (4, num_side_channel_elements,                       "num_side_channel_elements");
    Get_S1 (4, num_back_channel_elements,                       "num_back_channel_elements");
    Get_S1 (2, num_lfe_channel_elements,                        "num_lfe_channel_elements");
    Get_S1 (3, num_assoc_data_elements,                         "num_assoc_data_elements");
    Get_S1 (4, num_valid_cc_elements,                           "num_valid_cc_elements");
    TEST_SB_SKIP(                                               "mono_mixdown_present");
        Skip_S1(4,                                              "mono_mixdown_element_number");
    TEST_SB_END();
    TEST_SB_SKIP(                                               "stereo_mixdown_present");
        Skip_S1(4,                                              "stereo_mixdown_element_number");
    TEST_SB_END();
    TEST_SB_SKIP(                                               "matrix_mixdown_idx_present");
        Skip_S1(2,                                              "matrix_mixdown_idx");
        Skip_SB(                                                "pseudo_surround_enable");
    TEST_SB_END();
    bool front1_element_is_cpe=false;
    if (!num_side_channel_elements && num_back_channel_elements && num_back_channel_elements<3) // Hack: e.g. in case of 5.1, 7.1
    {
        num_side_channel_elements=1;
        num_back_channel_elements--;
    }
    for (int8u Pos=0; Pos<num_front_channel_elements; Pos++)
    {
        Element_Begin1("front_element");
        bool front_element_is_cpe;
        Get_SB (   front_element_is_cpe,                        "front_element_is_cpe");
        Skip_S1(4,                                              "front_element_tag_select");
        if (front_element_is_cpe)
        {
            Channels_Front+=2;
            Channels+=2;
            if (Pos==0)
                front1_element_is_cpe=true;
        }
        else
        {
            Channels_Front++;
            Channels++;
        }
        Element_End0();
    }
    for (int8u Pos=0; Pos<num_side_channel_elements; Pos++)
    {
        Element_Begin1("side_element");
        bool side_element_is_cpe;
        Get_SB (   side_element_is_cpe,                         "side_element_is_cpe");
        Skip_S1(4,                                              "side_element_tag_select");
        if (side_element_is_cpe)
        {
            Channels_Side+=2;
            Channels+=2;
        }
        else
        {
            Channels_Side++;
            Channels++;
        }
        Element_End0();
    }
    for (int8u Pos=0; Pos<num_back_channel_elements; Pos++)
    {
        Element_Begin1("back_element");
        bool back_element_is_cpe;
        Get_SB (   back_element_is_cpe,                         "back_element_is_cpe");
        Skip_S1(4,                                              "back_element_tag_select");
        if (back_element_is_cpe)
        {
            Channels_Back+=2;
            Channels+=2;
        }
        else
        {
            Channels_Back++;
            Channels++;
        }
        Element_End0();
    }
    for (int8u Pos=0; Pos<num_lfe_channel_elements; Pos++)
    {
        Element_Begin1("lfe_element");
        Skip_S1(4,                                              "lfe_element_tag_select");
        Channels_LFE++;
        Channels++;
        Element_End0();
    }
    for (int8u Pos=0; Pos<num_assoc_data_elements; Pos++)
    {
        Element_Begin1("assoc_data_element");
        Skip_S1(4,                                              "assoc_data_element_tag_select");
        Element_End0();
    }
    for (int8u Pos=0; Pos<num_valid_cc_elements; Pos++)
    {
        Element_Begin1("valid_cc_element");
        Skip_SB(                                                "cc_element_is_ind_sw");
        Skip_S1(4,                                              "valid_cc_element_tag_select");
        Element_End0();
    }
    BS_End(); //Byte align
    Get_B1 (comment_field_bytes,                                "comment_field_bytes");
    if (comment_field_bytes)
        Get_UTF8(comment_field_bytes, comment_field_data,       "comment_field_data");
    BS_Begin(); //The stream needs continuity in the bitstream
    Element_End0();
 
    //Filling
    Ztring Channels_Positions, Channels_Positions2, ChannelLayout;
    switch (Channels_Front)
    {
        case  0 : break;
        case  1 : Channels_Positions+=__T("Front: C"); ChannelLayout+=__T("C "); break;
        case  2 : Channels_Positions+=__T("Front: L R"); ChannelLayout+=__T("L R "); break;
        case  3 : Channels_Positions+=__T("Front: L C R"); ChannelLayout+=num_front_channel_elements==2?(front1_element_is_cpe?__T("L R C "):__T("C L R ")):__T("? ? ? "); break;
        case  5 : Channels_Positions+=__T("Front: L C R Lw Rw"); ChannelLayout+=num_front_channel_elements==3?(front1_element_is_cpe?__T("L R C Lw Rw "):__T("C L R Lw Rw ")):__T("? ? ? ? ? "); break;
        default : Channels_Positions+=__T("Front:"); Channels_Positions+=Ztring::ToZtring(Channels_Side); for (size_t i=0; i<Channels_Front; i++) ChannelLayout+=__T("? "); //Which config?
    }
    switch (Channels_Side)
    {
        case  0 : break;
        case  1 : Channels_Positions+=__T(", Side: C"); ChannelLayout+=__T("Cs "); break;
        case  2 : Channels_Positions+=__T(", Side: L R"); ChannelLayout+=__T("Ls Rs "); break;
        case  3 : Channels_Positions+=__T(", Side: L C R"); ChannelLayout+=__T("? ? ? "); break;
        default : Channels_Positions+=__T(", Side: "); Channels_Positions+=Ztring::ToZtring(Channels_Side); for (size_t i=0; i< Channels_Side; i++) ChannelLayout+=__T("? "); //Which config?
    }
    switch (Channels_Back)
    {
        case  0 : break;
        case  1 : Channels_Positions+=__T(", Back: C"); ChannelLayout+=__T("Cs "); break;
        case  2 : Channels_Positions+=__T(", Back: L R"); ChannelLayout+=__T("Lrs Rrs "); break;
        case  3 : Channels_Positions+=__T(", Back: L C R"); ChannelLayout+=__T("Lrs Rrs Cs "); break;
        default : Channels_Positions+=__T(", Back: "); Channels_Positions+=Ztring::ToZtring(Channels_Back); for (size_t i=0; i< Channels_Back; i++) ChannelLayout+=__T("? "); //Which config?
    }
    switch (Channels_LFE)
    {
        case  0 : break;
        case  1 : Channels_Positions+=__T(", LFE"); ChannelLayout+=__T("LFE "); break;
        case  2 : Channels_Positions+=__T(", LFE LFE2"); ChannelLayout+=__T("LFE LFE2"); break;
        default : Channels_Positions+=__T(", LFE: "); Channels_Positions+=Ztring::ToZtring(Channels_LFE); ChannelLayout+=__T("LFE "); for (size_t i=1; i<Channels_LFE; i++) ChannelLayout+=__T("? "); //Which config?
    }
    Channels_Positions2=Ztring::ToZtring(Channels_Front)+__T('/')
                       +Ztring::ToZtring(Channels_Side)+__T('/')
                       +Ztring::ToZtring(Channels_Back)
                       +(Channels_LFE?__T(".1"):__T(""));
    if (!ChannelLayout.empty())
        ChannelLayout.resize(ChannelLayout.size()-1);
 
    FILLING_BEGIN();
        //Integrity test
        if (Aac_sampling_frequency[sampling_frequency_index_Temp]==0 || Channels>24) // TODO: full_2023548870.mp4 is buggy
        {
            Trusted_IsNot("sampling frequency / channels");
            Skip_BS(Data_BS_Remain(),                               "(Unknown frequency)");
            return;
        }
 
        if (audioObjectType==(int8u)-1)
            audioObjectType=audioObjectType_Temp;
        if (sampling_frequency_index==(int8u)-1)
            sampling_frequency_index=sampling_frequency_index_Temp;
 
        Infos_General["Comment"]=comment_field_data;
 
        Infos["CodecID"].From_Number(audioObjectType);
        Infos["Format"].From_UTF8("AAC");
        Infos["Format_Profile"].From_UTF8(Aac_Format_Profile(audioObjectType));
        Infos["Codec"].From_UTF8(Aac_audioObjectType(audioObjectType));
        Infos["SamplingRate"].From_Number(Aac_sampling_frequency[sampling_frequency_index]);
        Infos["Channel(s)"].From_Number(Channels);
        Infos["ChannelPositions"]=Channels_Positions;
        Infos["ChannelPositions/String2"]=Channels_Positions2;
        Infos["ChannelLayout"]=ChannelLayout;
 
        if (!Infos["Format_Settings_SBR"].empty())
        {
            const Ztring SamplingRate=Infos["SamplingRate"];
            Infos["Format_Profile"]=__T("HE-AAC");
            Infos["SamplingRate"].From_Number((extension_sampling_frequency_index==(int8u)-1)?(Frequency_b*2):extension_sampling_frequency, 10);
            if (MediaInfoLib::Config.LegacyStreamDisplay_Get())
            {
                Infos["Format_Profile"]+=__T(" / LC");
                Infos["SamplingRate"]+=__T(" / ")+SamplingRate;
            }
            Infos["Format_Settings"]=__T("NBC"); // "Not Backward Compatible"
            Infos["Format_Settings_SBR"]=__T("Yes (NBC)"); // "Not Backward Compatible"
            Infos["Codec"]=Ztring().From_UTF8(Aac_audioObjectType(audioObjectType))+__T("-SBR");
        }
 
        if (!Infos["Format_Settings_PS"].empty())
            FillInfosHEAACv2(__T("NBC"));
    FILLING_END();
}
 
//***************************************************************************
// Elements - GA bitstream
//***************************************************************************
 
//---------------------------------------------------------------------------
void File_Aac::raw_data_block()
{
    raw_data_block_Pos=0;
 
    if (audioObjectType!=2)
    {
        Skip_BS(Data_BS_Remain(),                               "Data");
        Frame_Count++;
        return; //We test only AAC LC
    }
 
    if (sampling_frequency_index>=13)
    {
        Trusted_IsNot("(Problem)");
        Skip_BS(Data_BS_Remain(),                               "(Problem)");
        return;
    }
 
    //Parsing
    Element_Begin1("raw_data_block");
    int8u id_syn_ele=0, id_syn_ele_Previous;
    do
    {
        Element_Begin0();
        id_syn_ele_Previous=id_syn_ele;
        Get_S1 (3, id_syn_ele,                                  "id_syn_ele"); Param_Info1(Aac_id_syn_ele[id_syn_ele]); Element_Name(Aac_id_syn_ele[id_syn_ele]);
 
        #if MEDIAINFO_TRACE
            bool Trace_Activated_Save=Trace_Activated;
            if (id_syn_ele!=0x05)
                Trace_Activated=false; //It is too big, disabling trace for now for full AAC parsing
        #endif //MEDIAINFO_TRACE
 
        switch (id_syn_ele)
        {
            case 0x00 : single_channel_element();           break; //ID_SCE
            case 0x01 : channel_pair_element();             break; //ID_CPE
            case 0x02 : coupling_channel_element();         break; //ID_CCE
            case 0x03 : lfe_channel_element();              break; //ID_LFE
            case 0x04 : data_stream_element();              break; //ID_DSE
            case 0x05 : program_config_element();           break; //ID_PCE
            case 0x06 : fill_element(id_syn_ele_Previous);  break; //ID_FIL
            case 0x07 :                                     break; //ID_END
            default   :                                          ; //Can not happen
        }
        if (id_syn_ele<4) // All "content" element
            raw_data_block_Pos++;
 
        #if MEDIAINFO_TRACE
            Trace_Activated=Trace_Activated_Save;
        #endif //MEDIAINFO_TRACE
 
        Element_End0();
    }
    while(Element_IsOK() && Data_BS_Remain() && id_syn_ele!=0x07); //ID_END
    if (Element_IsOK() && id_syn_ele!=0x07)
        Trusted_IsNot("Not ending by END element");
    if (Element_IsOK() && Data_BS_Remain()%8)
        Skip_S1(Data_BS_Remain()%8,                             "byte_alignment");
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::single_channel_element()
{
    //Parsing
    Skip_S1 (4,                                                 "element_instance_tag");
    individual_channel_stream(false, false);
}
 
//---------------------------------------------------------------------------
void File_Aac::channel_pair_element()
{
    //Parsing
    Skip_S1(4,                                                  "element_instance_tag");
    Get_SB (common_window,                                      "common_window");
    if (common_window)
    {
        int8u ms_mask_present;
        ics_info();
        Get_S1(2, ms_mask_present,                              "ms_mask_present");
        if (ms_mask_present==1)
        {
            Element_Begin1("ms_mask");
            for (int8u g=0; g<num_window_groups; g++)
            {
                Element_Begin1("window");
                for (int8u sfb=0; sfb<max_sfb; sfb++)
                    Skip_SB(                                    "ms_used[g][sfb]");
                Element_End0();
            }
            Element_End0();
        }
    }
    individual_channel_stream(common_window, false);
    if (!Element_IsOK())
    {
        Skip_BS(Data_BS_Remain(),                               "(Problem)");
        return;
    }
    individual_channel_stream(common_window, false);
}
 
//---------------------------------------------------------------------------
void File_Aac::ics_info()
{
    //Parsing
    Element_Begin1("ics_info");
    Skip_SB(                                                    "ics_reserved_bit");
    Get_S1 (2, window_sequence,                                 "window_sequence"); Param_Info1(Aac_window_sequence[window_sequence]);
    Skip_SB(                                                    "window_shape");
    if (window_sequence==2) //EIGHT_SHORT_SEQUENCE
    {
        Get_S1 (4, max_sfb,                                     "max_sfb");
        Get_S1 (7, scale_factor_grouping,                       "scale_factor_grouping");
    }
    else
    {
        bool predictor_data_present;
        Get_S1 (6, max_sfb,                                     "max_sfb");
        Get_SB (   predictor_data_present,                      "predictor_data_present");
        if (predictor_data_present)
        {
            if (audioObjectType==1) //AAC Main
            {
                bool predictor_reset;
                Get_SB (predictor_reset,                        "predictor_reset");
                if (predictor_reset)
                    Skip_S1(5,                                  "predictor_reset_group_number");
                int8u PRED_SFB_MAX=max_sfb;
                if (PRED_SFB_MAX>Aac_PRED_SFB_MAX[sampling_frequency_index])
                    PRED_SFB_MAX=Aac_PRED_SFB_MAX[sampling_frequency_index];
                for (int8u sfb=0; sfb<PRED_SFB_MAX; sfb++)
                    Skip_SB(                                    "prediction_used[sfb]");
            }
            else
            {
                bool ltp_data_present;
                Get_SB (ltp_data_present,                       "ltp_data_present");
                if (ltp_data_present)
                    ltp_data();
                if (common_window)
                {
                    Get_SB (ltp_data_present,                   "ltp_data_present");
                    if (ltp_data_present)
                        ltp_data();
                }
            }
        }
    }
    Element_End0();
 
    //Calculation of windows
    switch (window_sequence)
    {
        case 0 :    //ONLY_LONG_SEQUENCE
        case 1 :    //LONG_START_SEQUENCE
        case 3 :    //LONG_STOP_SEQUENCE
                    num_windows=1;
                    num_window_groups=1;
                    window_group_length[0]=1;
                    num_swb=Aac_swb_offset_long_window[sampling_frequency_index]->num_swb;
                    for (int8u i=0; i<num_swb+1; i++)
                    {
                        if (Aac_swb_offset_long_window[sampling_frequency_index]->swb_offset[i]<frame_length)
                            swb_offset[i]=Aac_swb_offset_long_window[sampling_frequency_index]->swb_offset[i];
                        else
                            swb_offset[i]=frame_length;
                        sect_sfb_offset[0][i]=swb_offset[i];
                    }
                    break;
        case 2 :    //EIGHT_SHORT_SEQUENCE
                    num_windows=8;
                    num_window_groups=1;
                    window_group_length[0]=1;
                    num_swb=Aac_swb_offset_short_window[sampling_frequency_index]->num_swb;
                    for (int8u i=0; i<num_swb + 1; i++)
                        swb_offset[i] = Aac_swb_offset_short_window[sampling_frequency_index]->swb_offset[i];
                    swb_offset[num_swb] = frame_length/8;
                    for (int8u i=0; i<num_windows-1; i++)
                    {
                        if (!(scale_factor_grouping&(1<<(6-i))))
                        {
                            num_window_groups++;
                            window_group_length[num_window_groups-1]=1;
                        }
                        else
                            window_group_length[num_window_groups-1]++;
                    }
                    for (int g = 0; g < num_window_groups; g++)
                    {
                        int8u sect_sfb = 0;
                        int16u offset = 0;
                        for (int8u i=0; i<num_swb; i++)
                        {
                            int16u width = Aac_swb_offset_short_window[sampling_frequency_index]->swb_offset[i+1] - Aac_swb_offset_short_window[sampling_frequency_index]->swb_offset[i];
                            width *= window_group_length[g];
                            sect_sfb_offset[g][sect_sfb++] = offset;
                            offset += width;
                        }
                        sect_sfb_offset[g][sect_sfb] = offset;
                    }
                    break;
        default:    ;
    }
}
 
//---------------------------------------------------------------------------
void File_Aac::pulse_data()
{
    //Parsing
    int8u number_pulse;
    Get_S1(2,number_pulse,                                      "number_pulse");
    Skip_S1(6,                                                  "pulse_start_sfb");
    for (int i = 0; i < number_pulse+1; i++)
    {
        Skip_S1(5,                                              "pulse_offset[i]");
        Skip_S1(4,                                              "pulse_amp[i]");
    }
}
 
//---------------------------------------------------------------------------
void File_Aac::coupling_channel_element()
{
    //Parsing
    int8u num_coupled_elements;
    bool ind_sw_cce_flag;
    Skip_S1(4,                                                  "element_instance_tag");
    Get_SB (   ind_sw_cce_flag,                                 "ind_sw_cce_flag");
    Get_S1 (3, num_coupled_elements,                            "num_coupled_elements");
    size_t num_gain_element_lists=0;
    for (int8u c=0; c<num_coupled_elements+1; c++)
    {
        num_gain_element_lists++;
        bool cc_target_is_cpe;
        Get_SB (   cc_target_is_cpe,                            "cc_target_is_cpe[c]");
        Skip_S1(4,                                              "cc_target_tag_select[c]");
        if (cc_target_is_cpe)
        {
            bool cc_l, cc_r;
            Get_SB (cc_l,                                       "cc_l[c]");
            Get_SB (cc_r,                                       "cc_r[c]");
            if (cc_l && cc_r)
                num_gain_element_lists++;
        }
    }
    Skip_SB(                                                    "cc_domain");
    Skip_SB(                                                    "gain_element_sign");
    Skip_S1(2,                                                  "gain_element_scale");
    individual_channel_stream(false, false);
    if (!Element_IsOK())
    {
        Skip_BS(Data_BS_Remain(),                               "(Problem)");
        return;
    }
    bool cge;
    for (size_t c=1; c<num_gain_element_lists; c++)
    {
        if (ind_sw_cce_flag)
            cge = true;
        else
            Get_SB (cge,                                        "common_gain_element_present[c]");
        if (cge)
            hcod_sf(                                            "hcod_sf[common_gain_element[c]]");
        else
        {
            for (int g = 0; g < num_window_groups; g++)
            {
                for (int sfb=0; sfb<max_sfb; sfb++)
                {
                    if (sfb_cb[g][sfb]) //Not ZERO_HCB
                        hcod_sf(                                "hcod_sf[dpcm_gain_element[c][g][sfb]]");
                }
            }
        }
    }
}
 
//---------------------------------------------------------------------------
void File_Aac::lfe_channel_element()
{
    Skip_S1(4,                                                  "element_instance_tag");
    individual_channel_stream(false, false);
}
 
//---------------------------------------------------------------------------
void File_Aac::data_stream_element()
{
    bool data_byte_align_flag;
    int16u cnt;
    int8u  count;
    Skip_S1(4,                                                  "element_instance_tag");
    Get_SB (   data_byte_align_flag,                            "data_byte_align_flag");
    Get_S1 (8, count,                                           "count");
    cnt=count;
    if (cnt==255)
    {
        Get_S1(8, count,                                        "esc_count");
        cnt+=count;
    }
    if (data_byte_align_flag)
    {
        if (Data_BS_Remain()%8)
            Skip_S1(Data_BS_Remain()%8,                         "byte_alignment");
    }
    Element_Begin1("data_stream_byte[element_instance_tag]");
    for (int16u i=0; i<cnt; i++)
        Skip_S1(8,                                                "[i]");
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::fill_element(int8u id_syn_ele)
{
    //Parsing
    int8u  count;
    Get_S1 (4, count,                                           "count");
    size_t cnt=count;
    if (count==15)
    {
        int8u esc_count;
        Get_S1 (8, esc_count,                                   "esc_count");
        cnt+=esc_count-1;
    }
    if (cnt)
    {
        if (Data_BS_Remain()>=8*cnt)
        {
            size_t End=Data_BS_Remain()-8*cnt;
            extension_payload(End, id_syn_ele);
        }
        else
            Skip_BS(Data_BS_Remain(),                           "(Error)");
    }
}
 
//---------------------------------------------------------------------------
void File_Aac::gain_control_data()
{
    int8u max_band, adjust_num, aloc_bits, aloc_bits0;
    int8u wd_max=0;
    switch(window_sequence)
    {
        case 0 :    //ONLY_LONG_SEQUENCE
                    wd_max = 1;
                    aloc_bits0 = 5;
                    aloc_bits = 5;
                    break;
        case 1 :    //LONG_START_SEQUENCE
                    wd_max = 2;
                    aloc_bits0 = 4;
                    aloc_bits = 2;
                    break;
        case 2 :    //EIGHT_SHORT_SEQUENCE
                    wd_max = 8;
                    aloc_bits0 = 2;
                    aloc_bits = 2;
                    break;
        case 3 :    //LONG_STOP_SEQUENCE
                    wd_max = 2;
                    aloc_bits0 = 4;
                    aloc_bits = 5;
                    break;
        default:    return; //Never happens but makes compiler happy
    }
    Get_S1 (2, max_band,                                        "max_band");
    for (int8u bd=1; bd<=max_band; bd++)
    {
        for (int8u wd=0; wd<wd_max; wd++)
        {
            Get_S1(3, adjust_num,                               "adjust_num[bd][wd]");
            for (int8u ad=0; ad<adjust_num; ad++)
            {
                Skip_S1(4,                                      "alevcode[bd][wd][ad]");
                Skip_S1(wd==0?aloc_bits0:aloc_bits,             "aloccode[bd][wd][ad]");
            }
        }
    }
}
 
//***************************************************************************
// Elements - Subsidiary
//***************************************************************************
 
//---------------------------------------------------------------------------
void File_Aac::individual_channel_stream (bool common_window, bool scale_flag)
{
    Element_Begin1("individual_channel_stream");
    Skip_S1(8,                                                  "global_gain");
    if (!common_window && !scale_flag)
        ics_info();
    if (!Element_IsOK())
    {
        Skip_BS(Data_BS_Remain(),                               "(Problem)");
        Element_End0();
        return;
    }
   section_data();
    if (!Element_IsOK())
    {
        Skip_BS(Data_BS_Remain(), "?");
        Element_End0();
        return;
    }
    scale_factor_data();
    if (!Element_IsOK())
    {
        Skip_BS(Data_BS_Remain(),                               "(Problem)");
        Element_End0();
        return;
    }
    if (!scale_flag)
    {
        bool pulse_data_present;
        Get_SB (pulse_data_present,                             "pulse_data_present");
        if (pulse_data_present)
            pulse_data ();
        bool tns_data_present;
        Get_SB(tns_data_present,                                "tns_data_present");
        if (tns_data_present)
            tns_data ();
        bool gain_control_data_present;
        Get_SB(gain_control_data_present,                       "gain_control_data_present");
        if (gain_control_data_present)
            gain_control_data ();
    }
    if (!aacSpectralDataResilienceFlag)
        spectral_data ();
    else
    {
        Skip_BS(Data_BS_Remain(),                               "Not implemented");
        //~ length_of_reordered_spectral_data;
        //~ length_of_longest_codeword;
        //~ reordered_spectral_data ();
    }
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::section_data()
{
    Element_Begin1("section_data");
    int8u sect_esc_val;
    if (window_sequence==2) //EIGHT_SHORT_SEQUENCE
        sect_esc_val=(1<<3)-1;
    else
        sect_esc_val=(1<<5)-1;
    for (int8u g=0; g<num_window_groups; g++)
    {
        if (num_window_groups>1)
            Element_Begin1("windows");
        int8u k=0;
        int8u i=0;
        while (k<max_sfb)
        {
            if (aacSectionDataResilienceFlag)
                Get_S1(5, sect_cb[g][i],                        "sect_cb[g][i]");
            else
                Get_S1(4, sect_cb[g][i],                        "sect_cb[g][i]");
            int8u sect_len=0;
            int8u sect_len_incr;
            if (!aacSectionDataResilienceFlag || sect_cb[g][i]<11 || (sect_cb[g][i]>11 && sect_cb[g][i]<16))
            {
                for (;;)
                {
                    if (Data_BS_Remain()==0)
                    {
                        Trusted_IsNot("Size is wrong");
                        if (num_window_groups>1)
                            Element_End0();
                        Element_End0();
                        return; //Error
                    }
                    Get_S1 ((window_sequence==2?3:5), sect_len_incr, "sect_len_incr"); // (window_sequence == EIGHT_SHORT_SEQUENCE) => 3
                    if (sect_len_incr!=sect_esc_val)
                        break;
                    sect_len+=sect_esc_val;
                }
            }
            else
                sect_len_incr=1;
            sect_len+=sect_len_incr;
            sect_start[g][i]=k;
            sect_end[g][i]=k+sect_len;
            for (int16u sfb=k; sfb<k+sect_len; sfb++)
                sfb_cb[g][sfb]=sect_cb[g][i];
            k+= sect_len;
            i++;
            if (i>64)
            {
                Trusted_IsNot("Increment is wrong");
                if (num_window_groups>1)
                    Element_End0();
                Element_End0();
                return; //Error
            }
        }
        num_sec[g]=i;
        if (num_window_groups>1)
            Element_End0();
    }
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::scale_factor_data()
{
    Element_Begin1("scale_factor_data");
    if (!aacScalefactorDataResilienceFlag)
    {
        bool noise_pcm_flag=true;
        for (int g=0; g<num_window_groups; g++)
        {
            for (int8u sfb=0; sfb<max_sfb; sfb++)
            {
                if (sfb_cb[g][sfb]) //Not ZERO_HCB
                {
                    if (is_intensity( g, sfb))
                        hcod_sf(                                "hcod_sf[dpcm_is_position[g][sfb]]");
                    else
                    {
                        if (is_noise(g, sfb))
                        {
                            if (noise_pcm_flag)
                            {
                                noise_pcm_flag = 0;
                                Skip_S2(9,                      "dpcm_noise_nrg[g][sfb]");
                            }
                            else
                                hcod_sf(                        "hcod_sf[dpcm_noise_nrg[g][sfb]]");
                        }
                        else
                            hcod_sf(                            "hcod_sf[dpcm_sf[g][sfb]]");
                    }
                }
            }
        }
    }
    else
    {
        //scale_factor_data - part not implemented
        Skip_BS(Data_BS_Remain(),                               "Not implemented");
        //~ intensity_used = 0;
        //~ noise_used = 0;
        //~ sf_concealment;
        //~ rev_global_gain;
        //~ length_of_rvlc_sf;
        //~ for ( g = 0; g < num_window_groups; g++ ) {
            //~ for ( sfb=0; sfb < max_sfb; sfb++ ) {
                //~ if ( sfb_cb[g][sfb] ) { //Not ZERO_HCB
                    //~ if ( is_intensity ( g, sfb) ) {
                        //~ intensity_used = 1;
                        //~ rvlc_cod_sf[dpcm_is_position[g][sfb]];
                    //~ } else {
                        //~ if ( is_noise(g,sfb) ) {
                            //~ if ( ! noise_used ) {
                                //~ noise_used = 1;
                                //~ dpcm_noise_nrg[g][sfb];
                            //~ } else {
                                //~ rvlc_cod_sf[dpcm_noise_nrg[g][sfb]];
                            //~ }
                        //~ } else {
                            //~ rvlc_cod_sf[dpcm_sf[g][sfb]];
                        //~ }
                    //~ }
                //~ }
            //~ }
        //~ }
        //~ if ( intensity_used ) {
            //~ rvlc_cod_sf[dpcm_is_last_position];
        //~ }
        //~ noise_used = 0;
        //~ sf_escapes_present;
        //~ if ( sf_escapes_present ) {
            //~ length_of_rvlc_escapes;
            //~ for ( g = 0; g < num_window_groups; g++ ) {
                //~ for ( sfb = 0; sfb < max_sfb; sfb++ ) {
                    //~ if ( sfb_cb[g][sfb]) {  //Not ZERO_HCB
                        //~ if ( is_intensity ( g, sfb ) &&    dpcm_is_position[g][sfb] == ESC_FLAG ) {
                            //~ rvlc_esc_sf[dpcm_is_position[g][sfb]];
                        //~ } else {
                            //~ if ( is_noise ( g, sfb ) {
                                //~ if ( ! noise_used ) {
                                    //~ noise_used = 1;
                                //~ } else {
                                    //~ if (dpcm_noise_nrg[g][sfb] == ESC_FLAG ) {
                                        //~ rvlc_esc_sf[dpcm_noise_nrg[g][sfb]];
                                    //~ }
                                //~ }
                            //~ } else {
                                //~ if (dpcm_sf[g][sfb] == ESC_FLAG ) {
                                    //~ rvlc_esc_sf[dpcm_sf[g][sfb]];
                                //~ }
                            //~ }
                        //~ }
                    //~ }
                //~ }
            //~ }
            //~ if ( intensity_used && dpcm_is_last_position == ESC_FLAG ) {
                //~ rvlc_esc_sf[dpcm_is_last_position];
            //~ }
        //~ }
        //~ if ( noise_used ) {
            //~ dpcm_noise_last_position;
        //~ }
    }
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::tns_data()
{
    int8u n_filt_bits=2;
    int8u length_bits=6;
    int8u order_bits=5;
 
    if (window_sequence==2) //EIGHT_SHORT_SEQUENCE
    {
        n_filt_bits=1;
        length_bits=4;
        order_bits=3;
    }
 
    for (int8u w=0; w<num_windows; w++)
    {
        int8u start_coef_bits, n_filt;
        Get_S1(n_filt_bits, n_filt,                             "n_filt[w]");
        if (n_filt)
        {
            bool coef_res;
            Get_SB (coef_res,                                   "coef_res[w]");
            start_coef_bits=coef_res?4:3;
 
            for (int8u filt=0; filt<n_filt; filt++)
            {
                int8u order;
                Skip_S1(length_bits,                            "length[w][filt]");
                Get_S1 (order_bits, order,                      "order[w][filt]");
                if (order)
                {
                    bool coef_compress;
                    Skip_SB(                                    "direction[w][filt]");
                    Get_SB (coef_compress,                      "coef_compress[w][filt]");
                    int8u coef_bits=start_coef_bits-(coef_compress?1:0);
                    for (int8u i=0; i<order; i++)
                        Skip_S1(coef_bits,                      "coef[w][filt][i]");
                }
            }
        }
    }
}
 
//---------------------------------------------------------------------------
void File_Aac::ltp_data()
{
    Element_Begin1("ltp_data");
    //int sfb;
    //bool ltp_lag_update;
    //if (AudioObjectType == ER_AAC_LD ) {
        //~ Get_SB(ltp_lag_update,"ltp_lag_update");
        //~ if ( ltp_lag_update ) {
            //~ Get_S2(10,ltp_lag,"ltp_lag");
        //~ } else {
            //~ //ltp_lag = ltp_prev_lag;
        //~ }
        //~ Skip_S1(3,"ltp_coef");
        //~ for (sfb = 0; sfb <(max_sfb<MAX_LTP_LONG_SFB?max_sfb:MAX_LTP_LONG_SFB);& sfb++ ) {
            //~ Skip_SB("ltp_long_used[sfb]");
        //~ }
    //} else {
        Get_S2(11,ltp_lag,                                        "ltp_lag");
        Skip_S1(3,                                                "ltp_coef");
        if(window_sequence!=2) //EIGHT_SHORT_SEQUENCE
        {
            for (int8u sfb=0; sfb<(max_sfb<40?max_sfb:40); sfb++ ) //MAX_LTP_LONG_SFB=40
                Skip_SB("ltp_long_used[sfb]");
        }
    //}
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::spectral_data()
{
    Element_Begin1("spectral_data");
    for (int g = 0; g < num_window_groups; g++)
    {
        if (num_window_groups>1)
            Element_Begin1("windows");
        for (int8u i=0; i<num_sec[g]; i++)
        {
            switch (sect_cb[g][i])
            {
                case  0 :   //ZERO_HCB
                case 13 :   //NOISE_HCB
                case 14 :   //INTENSITY_HCB2
                case 15 :   //INTENSITY_HCB
                            break;
                default :
                            if (sect_end[g][i]>=num_swb+1)
                            {
                                Trusted_IsNot("(Problem)");
                                Skip_BS(Data_BS_Remain(),       "(Problem)");
                                if (num_window_groups>1)
                                    Element_End0();
                                Element_End0();
                                return;
                            }
                            for (int16u k=sect_sfb_offset[g][sect_start[g][i]]; k<sect_sfb_offset[g][sect_end[g][i]]; k+=(sect_cb[g][i]<5?4:2))
                            {
                                hcod(sect_cb[g][i],             "sect_cb");
                                if (!Element_IsOK())
                                {
                                    Skip_BS(Data_BS_Remain(),   "(Problem)");
                                    if (num_window_groups>1)
                                        Element_End0();
                                    Element_End0();
                                    return;
                                }
                            }
            }
        }
        if (num_window_groups>1)
            Element_End0();
    }
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::extension_payload(size_t End, int8u id_aac)
{
    Element_Begin1("extension_payload");
    int8u extension_type;
    Get_S1 (4, extension_type,                                  "extension_type");
    switch(extension_type)
    {
        case 11 :   dynamic_range_info(); break;                //EXT_DYNAMIC_RANGE
        case 12 :   sac_extension_data(End); break;             //EXT_SAC_DATA
        case 13 :   sbr_extension_data(End, id_aac, 0); break;  //EXT_SBR_DATA
        case 14 :   sbr_extension_data(End, id_aac, 1); break;  //EXT_SBR_DATA_CRC
        case  1 :   //EXT_FILL_DATA
                    Skip_S1(4,                                  "fill_nibble"); Param_Info1("must be 0000");
                    if (Data_BS_Remain()>End)
                    {
                        Element_Begin1("fill_byte");
                        while (Data_BS_Remain()>End)
                            Skip_S1(8,                          "fill_byte[i]"); Param_Info1("must be 10100101");
                        Element_End0();
                    }
                    break;
        case  2 :   //EXT_DATA_ELEMENT
                    int8u data_element_version;
                    Get_S1 (4,data_element_version,             "data_element_version");
                    switch(data_element_version)
                    {
                        case 0 :    //ANC_DATA
                                    {
                                    int16u dataElementLength=0;
                                    int8u dataElementLengthPart;
                                    do
                                    {
                                        Get_S1 (8, dataElementLengthPart, "dataElementLengthPart");
                                        dataElementLength+=dataElementLengthPart;
                                    }
                                    while (dataElementLengthPart==255);
                                    Skip_BS(8*dataElementLength, "data_element_byte[i]");
                                    }
                                    break;
                        default:    ;
                    }
                    break;
        case 0 : //EXT_FILL
        default:
            Skip_BS(Data_BS_Remain()-End,                       "other_bits");
    }
 
    Element_End0();
    if (End<Data_BS_Remain())
        Skip_BS(Data_BS_Remain()-End,                           "padding");
    if (Data_BS_Remain()!=End)
    {
        Skip_BS(Data_BS_Remain(),                               "Wrong size");
        Trusted_IsNot("Wrong size");
    }
}
 
//---------------------------------------------------------------------------
void File_Aac::dynamic_range_info()
{
    Element_Begin1("dynamic_range_info");
    int8u  drc_num_bands=1;
    bool   present;
    Get_SB (present,                                            "pce_tag_present");
    if (present)
    {
        Skip_S1(4,                                              "pce_ instance_tag");
        Skip_S1(4,                                              "drc_tag_reserved_bits");
    }
    Skip_SB(                                                    "excluded_chns_present");
    Get_SB (present,                                            "drc_bands_present");
    if (present)
    {
        int8u drc_band_incr;
        Get_S1 (4, drc_band_incr,                               "drc_band_incr");
        Skip_S1(4,                                              "drc_interpolation_scheme");
        drc_num_bands+=drc_band_incr;
        for (int8u i=0; i<drc_num_bands; i++)
        {
            Skip_S1(8,                                          "drc_band_top[i]");
        }
    }
    Get_SB (present,                                            "prog_ref_level_present");
    if (present)
    {
        Skip_S1(7,                                              "prog_ref_level");
        Skip_S1(1,                                              "prog_ref_level_reserved_bits");
    }
    for (int8u i=0; i<drc_num_bands; i++)
    {
        Skip_S1(1,                                              "dyn_rng_sgn[i]");
        Skip_S1(7,                                              "dyn_rng_ctl[i]");
    }
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::sac_extension_data(size_t End)
{
    Element_Begin1("sac_extension_data");
    Skip_S1(2,                                                  "ancType");
    Skip_SB(                                                    "ancStart");
    Skip_SB(                                                    "ancStop");
    Element_Begin1("ancDataSegmentByte");
    while (Data_BS_Remain()>End)
        Skip_S1(8,                                              "ancDataSegmentByte[i]");
    Element_End0();
    Element_End0();
}
 
//***************************************************************************
// Elements - Perceptual noise substitution (PNS)
//***************************************************************************
 
//---------------------------------------------------------------------------
int File_Aac::is_intensity(size_t group, size_t sfb)
{
    switch (sfb_cb[group][sfb])
    {
        case 15 :   return 1;
        case 14 :   return -1;
        default :   return 0;
    }
}
 
//---------------------------------------------------------------------------
bool File_Aac::is_noise(size_t group, size_t sfb)
{
    return (sfb_cb[group][sfb]==13);
}
//---------------------------------------------------------------------------
void File_Aac::hcod_sf(const char* Name)
{
    Element_Begin1(Name);
    int16u Pos=0;
 
    while (huffman_sf[Pos][1])
    {
        bool h;
        Get_SB (h,                                              "huffman");
        Pos+=huffman_sf[Pos][h];
 
        if (Pos>240)
        {
            Skip_BS(Data_BS_Remain(),                           "Error");
            Element_End0();
            return;
        }
    }
    Element_Info1(huffman_sf[Pos][0]-60);
    Element_End0();
 
    return;
}
 
//---------------------------------------------------------------------------
void File_Aac::hcod_2step(int8u CodeBook, int8s* Values, int8u Values_Count)
{
    int8u CodeWord;
    int8u ToRead=hcb_2step_Bytes[CodeBook];
    if ((size_t)ToRead>Data_BS_Remain())
        ToRead=(int8u)Data_BS_Remain(); //Read a maximum of remaining bytes
    Peek_S1(ToRead, CodeWord);
    int16u Offset=hcb_2step[CodeBook][CodeWord].Offset;
    int8u  Extra=hcb_2step[CodeBook][CodeWord].Extra;
 
    if (Extra)
    {
        Skip_BS(hcb_2step_Bytes[CodeBook],                            "extra");
        int8u Offset_inc;
        Peek_S1(Extra, Offset_inc);
        Offset+=Offset_inc;
        if(hcb_table[CodeBook][Offset][0]-hcb_2step_Bytes[CodeBook])
            Skip_BS(hcb_table[CodeBook][Offset][0]-hcb_2step_Bytes[CodeBook],"extra");
    }
    else
    {
        Skip_BS(hcb_table[CodeBook][Offset][0],                 "bits");
    }
 
    if (Offset>=hcb_table_size[CodeBook])
    {
        Skip_BS(Data_BS_Remain(),                               "Error");
        return;
    }
 
    for (int8u Pos=0; Pos<Values_Count; Pos++)
        Values[Pos]=hcb_table[CodeBook][Offset][Pos+1];
}
 
//---------------------------------------------------------------------------
void File_Aac::hcod_binary(int8u CodeBook, int8s* Values, int8u Values_Count)
{
    int16u Offset=0;
    while (!hcb_table[CodeBook][Offset][0])
    {
        bool b;
        Get_SB(b,                                               "huffman binary");
        Offset+=hcb_table[CodeBook][Offset][1+(b?1:0)];
    }
 
    if (Offset>=hcb_table_size[CodeBook])
    {
        Skip_BS(Data_BS_Remain(),                               "Error");
        return;
    }
 
    for (int8u Pos=0; Pos<Values_Count; Pos++)
        Values[Pos]=hcb_table[CodeBook][Offset][Pos+1];
}
 
 
 
//***************************************************************************
// Elements - Enhanced Low Delay Codec
//***************************************************************************
 
 
//---------------------------------------------------------------------------
void File_Aac::ELDSpecificConfig ()
{
    Element_Begin1("ELDSpecificConfig");
    Skip_SB("frameLengthFlag");
    Skip_SB("aacSectionDataResilienceFlag");
    Skip_SB("aacScalefactorDataResilienceFlag");
    Skip_SB("aacSpectralDataResilienceFlag");
 
    bool ldSbrPresentFlag;
    Get_SB(ldSbrPresentFlag,"ldSbrPresentFlag");
    if (ldSbrPresentFlag)
    {
        Skip_SB("ldSbrSamplingRate");
        Skip_SB("ldSbrCrcFlag");
        ld_sbr_header();
    }
 
    int8u eldExtType;
    for (;;)
    {
        Get_S1(4,eldExtType,"eldExtType");
        if (eldExtType == 0/*ELDEXT_TERM*/)
            break;
 
        int8u eldExtLen,eldExtLenAdd=0;
        int16u eldExtLenAddAdd;
        Get_S1(4,eldExtLen,"eldExtLen");
        int32u len = eldExtLen;
        if (eldExtLen == 15)
        {
            Get_S1(8,eldExtLenAdd,"eldExtLenAdd");
            len += eldExtLenAdd;
        }
        if (eldExtLenAdd==255)
        {
            Get_S2(16,eldExtLenAddAdd,"eldExtLenAddAdd");
            len += eldExtLenAdd;
        }
        //~ switch (eldExtType) {
            /* add future eld extension configs here */
                //~ default:
                for(int32u cnt=0; cnt<len; cnt++)
                    Skip_S1(8,"other_byte");
                //~ break;
        //~ }
 
    }
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::ld_sbr_header()
{
    int8u numSbrHeader;
    switch (channelConfiguration)
    {
        case 1:
        case 2:
            numSbrHeader = 1;
            break;
        case 3:
            numSbrHeader = 2;
            break;
        case 4:
        case 5:
        case 6:
            numSbrHeader = 3;
            break;
        case 7:
            numSbrHeader = 4;
            break;
        default:
            numSbrHeader = 0;
            break;
    }
 
    for (int el=0; el<numSbrHeader; el++) {
        //~ sbr_header();
        Element_Begin1("not implemented");
        Element_End0();
    }
}
 
//***************************************************************************
// Helpers
//***************************************************************************
 
//---------------------------------------------------------------------------
void File_Aac::hcod(int8u sect_cb, const char* Name)
{
    int8s Values[4];
 
    Element_Begin1(Name);
    switch (sect_cb)
    {
        case  1 :
        case  2 :
        case  4 :   //4-values, 2-step method
                    hcod_2step(sect_cb, Values, 4);
                    break;
        case  3 :   //4-values, binary search method
                    hcod_binary(sect_cb, Values, 4);
                    break;
        case  5 :
        case  7 :
        case  9 :   //2-values, binary search method
                    hcod_binary(sect_cb, Values, 2);
                    break;
        case  6 :
        case  8 :
        case 10 :
        case 11 :   //2-values, 2-step method
                    hcod_2step(sect_cb, Values, 2);
                    break;
        default:    Trusted_IsNot("(Problem)");
                    Element_End0();
                    return;
    }
 
    switch (sect_cb)
    {
        case  1 :
        case  2 :
        case  5 :
        case  6 :
                    break;
        default :   //With sign
                    for(int i=0; i<((sect_cb<5)?4:2); i++)
                        if(Values[i])
                            Skip_SB(                            "sign");
    }
 
    switch (sect_cb)
    {
        case 11 : //With hcod_esc
            for (int i=0; i<2; i++)
                if (Values[i]==16 || Values[i] == -16)
                {
                    Element_Begin1("hcod_esc");
                    bool Escape;
                    int BitCount=3;
                    do
                    {
                        BitCount++;
                        Get_SB(Escape,                          "bit count");
                    }
                    while (Escape);
 
 
                    Skip_BS(BitCount,                           "value");
                    Element_End0();
 
                }
            break;
        default: ;
    }
 
    Element_End0();
}
 
 
//---------------------------------------------------------------------------
void File_Aac::FillInfosHEAACv2(const Ztring& Format_Settings)
{
    Infos["Format_Profile"] = __T("HE-AACv2");
    const Ztring Channels = Infos["Channel(s)"];
    const Ztring ChannelPositions = Infos["ChannelPositions"];
    Infos["Channel(s)"] = __T("2");
    Infos["ChannelPositions"] = __T("Front: L R");
    if (MediaInfoLib::Config.LegacyStreamDisplay_Get())
    {
        const Ztring SamplingRate_Previous = Infos["SamplingRate"];
        Infos["Format_Profile"] += __T(" / HE-AAC / LC");
        Infos["Channel(s)"] += __T(" / ") + Channels + __T(" / ") + Channels;
        Infos["ChannelPositions"] += __T(" / ") + ChannelPositions + __T(" / ") + ChannelPositions;
        const int32u SamplingRate = (extension_sampling_frequency_index == (int8u)-1) ? (((int32u)Frequency_b) * 2) : extension_sampling_frequency;
        if (SamplingRate)
            Infos["SamplingRate"] = Ztring().From_Number(SamplingRate, 10) + __T(" / ") + SamplingRate_Previous;
    }
    if (Infos["Format_Settings"] != Format_Settings)
    {
        if (!Infos["Format_Settings"].empty())
            Infos["Format_Settings"].insert(0, __T(" / "));
        Infos["Format_Settings"].insert(0, Format_Settings);
    }
    Infos["Format_Settings_PS"] = __T("Yes (") + Format_Settings + __T(")");
    Infos["Codec"] = Ztring().From_UTF8(Aac_audioObjectType(audioObjectType)) + __T("-SBR-PS");
}
 
//***************************************************************************
// C++
//***************************************************************************
 
} //NameSpace
 
#endif //MEDIAINFO_AAC_YES

V640 The code's operational logic does not correspond with its formatting. The second statement will always be executed. It is possible that curly brackets are missing.

V524 It is odd that the body of 'lfe_channel_element' function is fully equivalent to the body of 'single_channel_element' function.

V688 The 'common_window' function argument possesses the same name as one of the class members, which can result in a confusion.

V688 The 'sect_cb' function argument possesses the same name as one of the class members, which can result in a confusion.

V793 It is odd that the result of the '-' operator is a part of the condition. Perhaps, this statement should have been compared with something else.