/*  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"
#if defined(MEDIAINFO_RIFF_YES)
    #include "MediaInfo/Multiple/File_Riff.h"
#endif
#include <cmath>
using namespace std;
//---------------------------------------------------------------------------
 
namespace MediaInfoLib
{
 
//***************************************************************************
// Speech coding (HVXC)
//***************************************************************************
 
//---------------------------------------------------------------------------
void File_Aac::HvxcSpecificConfig()
{
    Element_Begin1("HvxcSpecificConfig");
    bool isBaseLayer;
    Get_SB(isBaseLayer,                                         "isBaseLayer");
    if (isBaseLayer)
        HVXCconfig();
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::HVXCconfig()
{
    Element_Begin1("HVXCconfig");
    Skip_SB(                                                    "HVXCvarMode");
    Skip_S1(2,                                                  "HVXCrateMode");
    Skip_SB(                                                    "extensionFlag");
    //~ if (extensionFlag) {
        /*< to be defined in MPEG-4 Version 2 >*/
    //~ }
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::ErrorResilientHvxcSpecificConfig() {
    Element_Begin1("ErrorResilientHvxcSpecificConfig");
    bool isBaseLayer;
    Get_SB(isBaseLayer,"isBaseLayer");
    if (isBaseLayer) {
        ErHVXCconfig();
    }
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::ErHVXCconfig()
{
    Element_Begin1("ErHVXCconfig");
    bool extensionFlag;
    Skip_SB(                                                    "HVXCvarMode");
    Skip_S1(2,                                                  "HVXCrateMode");
    Get_SB (extensionFlag,                                      "extensionFlag");
 
    if (extensionFlag) {
        Skip_SB(                                                "var_ScalableFlag");
    }
    Element_End0();
}
 
//***************************************************************************
// Speech Coding (CELP)
//***************************************************************************
 
//---------------------------------------------------------------------------
void File_Aac::CelpSpecificConfig ()
{
    Element_Begin1("CelpSpecificConfig");
    bool isBaseLayer;
    Get_SB(isBaseLayer,                                         "isBaseLayer");
    if (isBaseLayer)
    {
        CelpHeader ();
    }
    else
    {
        bool isBWSLayer;
        Get_SB(isBWSLayer,                                      "isBWSLayer");
        if (isBWSLayer)
        {
            //~ CelpBWSenhHeader ()
            //~ {
            Skip_S1(2,                                          "BWS_configuration");
            //~ }
 
        }
        else
        {
            Skip_S1(2,                                          "CELP-BRS-id");
        }
    }
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::CelpHeader ()
{
    Element_Begin1("CelpHeader");
    bool ExcitationMode;
    Get_SB(ExcitationMode,                                      "ExcitationMode");
    Skip_SB(                                                    "SampleRateMode");
    Skip_SB(                                                    "FineRateControl");
    if (ExcitationMode == 1/*RPE*/)
    {
        Skip_S1(3,                                              "RPE_Configuration");
    }
    if (ExcitationMode == 0/*MPE*/)
    {
        Skip_S1(5,                                              "MPE_Configuration");
        Skip_S1(2,                                              "NumEnhLayers");
        Skip_SB(                                                "BandwidthScalabilityMode");
    }
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::ErrorResilientCelpSpecificConfig ()
{
    Element_Begin1("ErrorResilientCelpSpecificConfig");
    bool isBaseLayer;
    Get_SB(isBaseLayer,                                         "isBaseLayer");
    if (isBaseLayer)
    {
        ER_SC_CelpHeader ();
    }
    else
    {
        bool isBWSLayer;
        Get_SB(isBWSLayer,                                      "isBWSLayer");
        if (isBWSLayer)
        {
            //~ CelpBWSenhHeader ()
            //~ {
            Skip_S1(2,                                          "BWS_configuration");
            //~ }
 
        }
        else
        {
            Skip_S1(2,                                          "CELP-BRS-id");
        }
    }
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::ER_SC_CelpHeader ()
{
    Element_Begin1("ER_SC_CelpHeader");
    bool ExcitationMode;
    Get_SB(ExcitationMode,                                      "ExcitationMode");
    Skip_SB(                                                    "SampleRateMode");
    Skip_SB(                                                    "FineRateControl");
    Skip_SB(                                                    "SilenceCompression");
 
    if (ExcitationMode == 1/*RPE*/) {
        Skip_S1(3,                                              "RPE_Configuration");
    }
    if (ExcitationMode == 0/*MPE*/) {
        Skip_S1(5,                                              "MPE_Configuration");
        Skip_S1(2,                                              "NumEnhLayers");
        Skip_SB(                                                "BandwidthScalabilityMode");
    }
    Element_End0();
}
 
//***************************************************************************
// Structured Audio (SA)
//***************************************************************************
 
//***************************************************************************
// Text to Speech Interface (TTSI)
//***************************************************************************
 
//---------------------------------------------------------------------------
void File_Aac::TTSSpecificConfig()
{
    Element_Begin1("TTSSpecificConfig");
    //~ TTS_Sequence()
    //~ {
    Skip_S1(5,                                                  "TTS_Sequence_ID");
    Skip_BS(18,                                                 "Language_Code");
    Skip_SB(                                                    "Gender_Enable");
    Skip_SB(                                                    "Age_Enable");
    Skip_SB(                                                    "Speech_Rate_Enable");
    Skip_SB(                                                    "Prosody_Enable");
    Skip_SB(                                                    "Video_Enable");
    Skip_SB(                                                    "Lip_Shape_Enable");
    Skip_SB(                                                    "Trick_Mode_Enable");
    //~ }
    Element_End0();
}
 
//***************************************************************************
// Parametric Audio (HILN)
//***************************************************************************
 
//---------------------------------------------------------------------------
void File_Aac::HILNconfig()
{
    Element_Begin1("HILNconfig");
    Skip_SB(                                                    "HILNquantMode");
    Skip_S1(8,                                                  "HILNmaxNumLine");
    Skip_S1(4,                                                  "HILNsampleRateCode");
    Skip_S2(12,                                                 "HILNframeLength");
    Skip_S1(2,                                                  "HILNcontMode");
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::HILNenexConfig()
{
    Element_Begin1("HILNenexConfig");
    bool HILNenhaLayer;
    Get_SB(HILNenhaLayer,                                       "HILNenhaLayer");
    if (HILNenhaLayer)
        Skip_S1(2,                                              "HILNenhaQuantMode");
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::ParametricSpecificConfig()
{
    Element_Begin1("ParametricSpecificConfig");
    bool isBaseLayer;
    Get_SB(isBaseLayer,                                         "isBaseLayer");
    if (isBaseLayer)
        PARAconfig();
    else
        HILNenexConfig();
    Element_End0();
}
 
//---------------------------------------------------------------------------
void File_Aac::PARAconfig()
{
    Element_Begin1("PARAconfig");
    int8u PARAmode;
    Get_S1(2,PARAmode,                                          "PARAmode");
    if (PARAmode != 1)
        ErHVXCconfig();
    if (PARAmode != 0)
        HILNconfig();
    bool PARAextensionFlag;
    Get_SB(PARAextensionFlag,                                   "PARAextensionFlag");
    if (PARAextensionFlag) {
        /* to be defined in MPEG-4 Phase 3 */
    }
    Element_End0();
}
 
//***************************************************************************
// Technical description of parametric coding for high quality audio
//***************************************************************************
 
//---------------------------------------------------------------------------
void File_Aac::SSCSpecificConfig ()
{
    Element_Begin1("SSCSpecificConfig");
    Skip_S1(2,"decoder_level");
    Skip_S1(4,"update_rate");
    Skip_S1(2,"synthesis_method");
    if (channelConfiguration != 1)
    {
        int8u mode_ext;
        Get_S1(2,mode_ext,"mode_ext");
        if ((channelConfiguration == 2) && (mode_ext == 1))
        {
            /*reserved*/
        }
    }
    Element_End0();
}
 
//***************************************************************************
// MPEG-1/2 Audio
//***************************************************************************
 
//---------------------------------------------------------------------------
void File_Aac::MPEG_1_2_SpecificConfig()
{
    Element_Begin1("MPEG_1_2_SpecificConfig");
    Skip_SB(                                                    "extension");
    Element_End0();
}
 
//***************************************************************************
// Technical description of lossless coding of oversampled audio
//***************************************************************************
 
//---------------------------------------------------------------------------
void File_Aac::DSTSpecificConfig()
{
    Element_Begin1("DSTSpecificConfig");
    Skip_SB("DSDDST_Coded");
    Skip_S2(14,"N_Channels");
    Skip_SB("reserved");
    Element_End0();
}
 
//***************************************************************************
// Audio Lossless
//***************************************************************************
 
//---------------------------------------------------------------------------
void File_Aac::ALSSpecificConfig()
{
    //Not in spec, but something weird in the example I have
    int32u Junk;
    while (Data_BS_Remain())
    {
        Peek_S4(32, Junk);
        if (Junk!=0x414C5300)
        {
            Skip_SB(                                            "Unknown");
        }
        else
            break;
    }
    if (Data_BS_Remain()==0)
        return; //There is a problem
 
    Element_Begin1("ALSSpecificConfig");
    bool chan_config,chan_sort,crc_enabled,aux_data_enabled;
    int32u samp_freq, samples;
    int16u channels,frame_length;
    int8u ra_flag,random_access, file_type;
    Skip_BS(32,"als_id");
    Get_BS (32, samp_freq,                                      "samp_freq");
    Get_BS (32, samples,                                        "samples");
    Get_S2 (16, channels,                                       "channels"); Param_Info2(channels+1, " channel(s)");
    Get_S1 (3, file_type,                                       "file_type");
    Skip_S1(3,"resolution");
    Skip_SB("floating");
    Skip_SB("msb_first");
    Get_S2 (16,frame_length,"frame_length");
    Get_S1 (8,random_access,"random_access");
    Get_S1 (2,ra_flag,"ra_flag");
    Skip_SB("adapt_order");
    Skip_S1(2,"coef_table");
    Skip_SB("long_term_prediction");
    Skip_S2(10,"max_order");
    Skip_S1(2,"block_switching");
    Skip_SB("bgmc_mode");
    Skip_SB("sb_part");
    Skip_SB("joint_stereo");
    Skip_SB("mc_coding");
    Get_SB (chan_config,"chan_config");
    Get_SB (chan_sort,"chan_sort");
    Get_SB (crc_enabled,"crc_enabled");
    Skip_SB("RLSLMS");
    Skip_BS(5,"(reserved)");
    Get_SB (aux_data_enabled,"aux_data_enabled");
    if (chan_config)
        Skip_S2(16,"chan_config_info");
    if (chan_sort)
    {
        int16u ChBits=(int16u)ceil(log((double)(channels+1))/log((double)2));
        for (int8u c=0; c<=channels; c++)
            Skip_BS(ChBits,                                     "chan_pos[c]");
    }
    if(Data_BS_Remain()%8)
        Skip_S1(Data_BS_Remain()%8,                             "byte_align");
    BS_End();
    int32u header_size,trailer_size;
    Get_B4(header_size,                                         "header_size");
    Get_B4(trailer_size,                                        "trailer_size");
    #ifdef MEDIAINFO_RIFF_YES
    if (file_type==1) //WAVE file
    {
        Element_Begin1("orig_header");
        File_Riff MI;
        Open_Buffer_Init(&MI);
        Open_Buffer_Continue(&MI, Buffer+Buffer_Offset+(size_t)Element_Offset, header_size);
        Element_Offset+=header_size;
        File__Analyze::Finish(&MI); //No merge of data, only for trace information, because this is the data about the decoded stream, not the encoded stream
        Element_End0();
    }
    else
    #endif //MEDIAINFO_RIFF_YES
        Skip_XX(header_size,                                    "orig_header[]");
 
    Skip_XX(trailer_size,                                       "orig_trailer[]");
    if (crc_enabled)
        Skip_B4(                                                "crc");
    if ((ra_flag == 2) && (random_access > 0))
        for (int32u f=0; f<((samples-1)/(frame_length+1))+1; f++)
            Skip_B4(                                            "ra_unit_size[f]");
    if (aux_data_enabled)
    {
        int32u aux_size;
        Get_B4(aux_size,                                        "aux_size");
        Skip_XX(aux_size,                                       "aux_data[]");
    }
    Element_End0();
    BS_Begin(); //To be in sync with other objectTypes
 
    FILLING_BEGIN();
        //Filling
        File__Analyze::Stream_Prepare(Stream_Audio);
        Fill(Stream_Audio, StreamPos_Last, Audio_Channel_s_, channels+1);
 
        //Forcing default confignuration (something weird in the example I have)
        channelConfiguration=0;
        sampling_frequency_index=(int8u)-1;
        Frequency_b=samp_freq;
    FILLING_END();
}
 
//***************************************************************************
// Scalable lossless
//***************************************************************************
 
//---------------------------------------------------------------------------
void File_Aac::SLSSpecificConfig()
{
    Element_Begin1("SLSSpecificConfig");
    Skip_S1(3,"pcmWordLength");
    Skip_SB("aac_core_present");
    Skip_SB("lle_main_stream");
    Skip_SB("reserved_bit");
    Skip_S1(3,"frameLength");
    if (!channelConfiguration)
        program_config_element();
    Element_End0();
}
 
} //NameSpace
 
#endif //MEDIAINFO_AAC_YES
 

V523 The 'then' statement is equivalent to the 'else' statement.

V523 The 'then' statement is equivalent to the 'else' statement.

V525 The code contains the collection of similar blocks. Check items 'Skip_S1_', 'Skip_S1_', 'Skip_S2_', 'Skip_S1_' in lines 231, 232, 233, 234.

V525 The code contains the collection of similar blocks. Check items '2', '4', '2' in lines 288, 289, 290.

V688 The 'frame_length' local variable possesses the same name as one of the class members, which can result in a confusion.