Ejemplo n.º 1
0
Int32 sbr_crc_check(BIT_BUFFER * hBitBuf, UInt32 NrBits)
{
    Int32 crcResult = 1;
    BIT_BUFFER BitBufferCRC;
    UInt32 NrCrcBits;

    UInt32 crcCheckSum;

    Int32 i;
    CRC_BUFFER CrcBuf;
    UInt32 bValue;
    Int32 CrcStep;
    Int32 CrcNrBitsRest;

    crcCheckSum = buf_getbits(hBitBuf, SI_SBR_CRC_BITS);


    /*
     *    Copy Bit buffer State
     */

    BitBufferCRC.char_ptr       = hBitBuf->char_ptr;
    BitBufferCRC.buffer_word    = hBitBuf->buffer_word;
    BitBufferCRC.buffered_bits  = hBitBuf->buffered_bits;
    BitBufferCRC.nrBitsRead     = hBitBuf->nrBitsRead;
    BitBufferCRC.bufferLen      = hBitBuf->bufferLen;


    NrCrcBits = min(NrBits, BitBufferCRC.bufferLen - BitBufferCRC.nrBitsRead);


    CrcStep = NrCrcBits / MAXCRCSTEP;
    CrcNrBitsRest = (NrCrcBits - CrcStep * MAXCRCSTEP);

    CrcBuf.crcState = CRCSTART;
    CrcBuf.crcMask  = CRCMASK;
    CrcBuf.crcPoly  = CRCPOLY;

    for (i = 0; i < CrcStep; i++)
    {
        bValue = buf_getbits(&BitBufferCRC, MAXCRCSTEP);
        check_crc(&CrcBuf, bValue, MAXCRCSTEP);
    }

    bValue = buf_getbits(&BitBufferCRC, CrcNrBitsRest);
    check_crc(&CrcBuf, bValue, CrcNrBitsRest);

    if ((UInt32)(CrcBuf.crcState & CRCRANGE) != crcCheckSum)
    {
        crcResult = 0;
    }

    return (crcResult);
}
void sbr_get_additional_data(SBR_FRAME_DATA * hFrameData,
                             BIT_BUFFER     * hBitBuf)
{
    Int32 i;

    Int32 flag = buf_getbits(hBitBuf, 1);

    if (flag)
    {
        for (i = 0; i < hFrameData->nSfb[HI]; i++)
        {
            hFrameData->addHarmonics[i] = buf_getbits(hBitBuf, 1);
        }
    }
}
SBR_ERROR sbr_read_data(SBRDECODER_DATA * self,
                        SBR_DEC * sbrDec,
                        SBRBITSTREAM *stream)
{
    SBR_ERROR sbr_err =  SBRDEC_OK;
    int32_t SbrFrameOK = 1;
    int32_t sbrCRCAlwaysOn = 0;

    UInt32 bs_header_flag = 0;

    SBR_HEADER_STATUS headerStatus = HEADER_OK;

    SBR_CHANNEL *SbrChannel = self->SbrChannel;

    int32_t zeropadding_bits;

    BIT_BUFFER bitBuf ;

    /*
     *  evaluate Bitstream
     */

    bitBuf.buffer_word    = 0;
    bitBuf.buffered_bits  = 0;
    bitBuf.nrBitsRead     = 0;

    bitBuf.char_ptr  =  stream->sbrElement[0].Data;
    bitBuf.bufferLen = (stream->sbrElement[0].Payload) << 3;


    /*
     *  we have to skip a nibble because the first element of Data only
     *  contains a nibble of data !
     */
    buf_getbits(&bitBuf, LEN_NIBBLE);

    if ((stream->sbrElement[0].ExtensionType == SBR_EXTENSION_CRC) ||
            sbrCRCAlwaysOn)
    {
        int32_t CRCLen = ((stream->sbrElement[0].Payload - 1) << 3) + 4 - SI_SBR_CRC_BITS;
        SbrFrameOK = sbr_crc_check(&bitBuf, CRCLen);
    }


    if (SbrFrameOK)
    {
        /*
         *  The sbr data seems ok, if the header flag is set we read the header
         *  and check if vital parameters have changed since the previous frame.
         *  If the syncState equals UPSAMPLING, the SBR Tool has not been
         *  initialised by SBR header data, and can only do upsampling
         */

        bs_header_flag = buf_getbits(&bitBuf, 1);  /* read Header flag */

        if (bs_header_flag)
        {
            /*
             *  If syncState == SBR_ACTIVE, it means that we've had a SBR header
             *  before, and we will compare with the previous header to see if a
             *  reset is required. If the syncState equals UPSAMPLING this means
             *  that the SBR-Tool so far is only initialised to do upsampling
             *  and hence we need to do a reset, and initialise the system
             *  according to the present header.
             */

            headerStatus = sbr_get_header_data(&(SbrChannel[0].frameData.sbr_header),
                                               &bitBuf,
                                               SbrChannel[0].syncState);
        }     /* if (bs_header_flag) */


        switch (stream->sbrElement[0].ElementID)
        {
            case SBR_ID_SCE :

                /* change of control data, reset decoder */
                if (headerStatus == HEADER_RESET)
                {
                    sbr_err = sbr_reset_dec(&(SbrChannel[0].frameData),
                                            sbrDec,
                                            self->SbrChannel[0].frameData.sbr_header.sampleRateMode);

                    if (sbr_err != SBRDEC_OK)
                    {
                        break;
                    }
                    /*
                     * At this point we have a header and the system has been reset,
                     * hence syncState from now on will be SBR_ACTIVE.
                     */
                    SbrChannel[0].syncState     = SBR_ACTIVE;
                }

                if ((SbrChannel[0].syncState == SBR_ACTIVE))
                {
                    sbr_err = sbr_get_sce(&(SbrChannel[0].frameData),
                                          &bitBuf
#ifdef PARAMETRICSTEREO
                                          , self->hParametricStereoDec
#endif
                                         );

                    if (sbr_err != SBRDEC_OK)
                    {
                        break;
                    }
                }

                break;

            case SBR_ID_CPE :

                if (bs_header_flag)
                {
                    pv_memcpy(&(SbrChannel[1].frameData.sbr_header),
                              &(SbrChannel[0].frameData.sbr_header),
                              sizeof(SBR_HEADER_DATA));
                }

                /* change of control data, reset decoder */
                if (headerStatus == HEADER_RESET)
                {
                    for (int32_t lr = 0 ; lr < 2 ; lr++)
                    {
                        sbr_err = sbr_reset_dec(&(SbrChannel[lr].frameData),
                                                sbrDec,
                                                self->SbrChannel[0].frameData.sbr_header.sampleRateMode);

                        if (sbr_err != SBRDEC_OK)
                        {
                            break;
                        }

                        SbrChannel[lr].syncState = SBR_ACTIVE;
                    }
                }

                if (SbrChannel[0].syncState == SBR_ACTIVE)
                {
                    sbr_err = sbr_get_cpe(&(SbrChannel[0].frameData),
                                          &(SbrChannel[1].frameData),
                                          &bitBuf);

                    if (sbr_err != SBRDEC_OK)
                    {
                        break;
                    }

                }
                break;

            default:
                sbr_err = SBRDEC_ILLEGAL_PLUS_ELE_ID;
                break;
        }

    }           /* if (SbrFrameOK) */

    /*
     *  Check that the bits read did not go beyond SBR frame boundaries
     */

    zeropadding_bits = (8 - (bitBuf.nrBitsRead & 0x7)) & 0x7;

    if ((bitBuf.nrBitsRead + zeropadding_bits)  > bitBuf.bufferLen)
    {
        sbr_err = SBRDEC_INVALID_BITSTREAM;
    }

    return sbr_err;
}
SBR_ERROR extractFrameInfo(BIT_BUFFER     * hBitBuf,
                           SBR_FRAME_DATA * h_frame_data)
{

    Int32 absBordLead = 0;
    Int32 nRelLead = 0;
    Int32 nRelTrail = 0;
    Int32 bs_num_env = 0;
    Int32 bs_num_rel = 0;
    Int32 bs_var_bord = 0;
    Int32 bs_var_bord_0 = 0;
    Int32 bs_var_bord_1 = 0;
    Int32 bs_pointer = 0;
    Int32 bs_pointer_bits;
    Int32 frameClass;
    Int32 temp;
    Int32 env;
    Int32 k;
    Int32 bs_num_rel_0 = 0;
    Int32 bs_num_rel_1 = 0;
    Int32 absBordTrail = 0;
    Int32 middleBorder = 0;
    Int32 bs_num_noise;
    Int32 lA = 0;

    Int32 tE[MAX_ENVELOPES + 1];
    Int32 tQ[2 + 1];
    Int32 f[MAX_ENVELOPES + 1];
    Int32 bs_rel_bord[3];
    Int32 bs_rel_bord_0[3];
    Int32 bs_rel_bord_1[3];
    Int32 relBordLead[3];
    Int32 relBordTrail[3];


    Int32 *v_frame_info = h_frame_data->frameInfo;

    SBR_ERROR err =  SBRDEC_OK;


    /*
     * First read from the bitstream.
     */

    /* Read frame class */
    h_frame_data->frameClass = frameClass = buf_getbits(hBitBuf, SBR_CLA_BITS);


    switch (frameClass)
    {

        case FIXFIX:
            temp = buf_getbits(hBitBuf, SBR_ENV_BITS);   /* 2 bits */

            bs_num_env = 1 << temp;


            f[0] = buf_getbits(hBitBuf, SBR_RES_BITS);   /* 1 bit */

            for (env = 1; env < bs_num_env; env++)
            {
                f[env] = f[0];
            }

            nRelLead     = bs_num_env - 1;
            absBordTrail  = 16;


            break;

        case FIXVAR:
            bs_var_bord = buf_getbits(hBitBuf, SBR_ABS_BITS);   /* 2 bits */
            bs_num_rel  = buf_getbits(hBitBuf, SBR_NUM_BITS);   /* 2 bits */
            bs_num_env  = bs_num_rel + 1;

            for (k = 0; k < bs_num_env - 1; k++)
            {
                bs_rel_bord[k] = (buf_getbits(hBitBuf, SBR_REL_BITS) + 1) << 1;
            }

            bs_pointer_bits = bs_pointer_bits_tbl[bs_num_env];

            bs_pointer = buf_getbits(hBitBuf, bs_pointer_bits);

            for (env = 0; env < bs_num_env; env++)
            {                                                    /* 1 bit */
                f[bs_num_env - 1 - env] = buf_getbits(hBitBuf, SBR_RES_BITS);
            }

            absBordTrail  = 16 + bs_var_bord;
            nRelTrail     = bs_num_rel;

            break;

        case VARFIX:
            bs_var_bord = buf_getbits(hBitBuf, SBR_ABS_BITS);   /* 2 bits */
            bs_num_rel  = buf_getbits(hBitBuf, SBR_NUM_BITS);   /* 2 bits */
            bs_num_env  = bs_num_rel + 1;

            for (k = 0; k < bs_num_env - 1; k++)
            {
                bs_rel_bord[k] = (buf_getbits(hBitBuf, SBR_REL_BITS) + 1) << 1;
            }

            bs_pointer_bits = bs_pointer_bits_tbl[bs_num_env];

            bs_pointer = buf_getbits(hBitBuf, bs_pointer_bits);

            for (env = 0; env < bs_num_env; env++)
            {                                  /* 1 bit */
                f[env] = buf_getbits(hBitBuf, SBR_RES_BITS);
            }

            absBordTrail = 16;
            absBordLead  = bs_var_bord;
            nRelLead     = bs_num_rel;

            break;

        case VARVAR:
            bs_var_bord_0 = buf_getbits(hBitBuf, SBR_ABS_BITS);   /* 2 bits */
            bs_var_bord_1 = buf_getbits(hBitBuf, SBR_ABS_BITS);
            bs_num_rel_0  = buf_getbits(hBitBuf, SBR_NUM_BITS);   /* 2 bits */
            bs_num_rel_1  = buf_getbits(hBitBuf, SBR_NUM_BITS);

            bs_num_env = bs_num_rel_0 + bs_num_rel_1 + 1;

            for (k = 0; k < bs_num_rel_0; k++)
            {                                                 /* 2 bits */
                bs_rel_bord_0[k] = (buf_getbits(hBitBuf, SBR_REL_BITS) + 1) << 1;
            }

            for (k = 0; k < bs_num_rel_1; k++)
            {                                                 /* 2 bits */
                bs_rel_bord_1[k] = (buf_getbits(hBitBuf, SBR_REL_BITS) + 1) << 1;
            }


            bs_pointer_bits = bs_pointer_bits_tbl[bs_num_env];

            bs_pointer = buf_getbits(hBitBuf, bs_pointer_bits);

            for (env = 0; env < bs_num_env; env++)
            {                                  /* 1 bit */
                f[env] = buf_getbits(hBitBuf, SBR_RES_BITS);
            }

            absBordLead   = bs_var_bord_0;
            absBordTrail  = 16 + bs_var_bord_1;
            nRelLead      = bs_num_rel_0;
            nRelTrail     = bs_num_rel_1;

            break;

    };


    /*
     * Calculate the framing.
     */


    switch (frameClass)
    {
        case FIXFIX:
            for (k = 0; k < nRelLead; k++)
            {
                relBordLead[k] = T_16_ov_bs_num_env_tbl[bs_num_env];
            }
            break;
        case VARFIX:
            for (k = 0; k < nRelLead; k++)
            {
                relBordLead[k] = bs_rel_bord[k];
            }
            break;
        case VARVAR:
            for (k = 0; k < nRelLead; k++)
            {
                relBordLead[k] = bs_rel_bord_0[k];
            }
            for (k = 0; k < nRelTrail; k++)
            {
                relBordTrail[k] = bs_rel_bord_1[k];
            }
            break;
        case FIXVAR:
            for (k = 0; k < nRelTrail; k++)
            {
                relBordTrail[k] = bs_rel_bord[k];
            }
            break;
    }


    tE[0]          = absBordLead;
    tE[bs_num_env] = absBordTrail;

    for (env = 1; env <= nRelLead; env++)
    {
        tE[env] = absBordLead;
        for (k = 0; k <= env - 1; k++)
        {
            tE[env] += relBordLead[k];
        }
    }

    for (env = nRelLead + 1; env < bs_num_env; env++)
    {
        tE[env] = absBordTrail;
        for (k = 0; k <= bs_num_env - env - 1; k++)
        {
            tE[env] -= relBordTrail[k];
        }
    }



    switch (frameClass)
    {
        case  FIXFIX:
            middleBorder = bs_num_env >> 1;
            break;
        case VARFIX:
            switch (bs_pointer)
            {
                case 0:
                    middleBorder = 1;
                    break;
                case 1:
                    middleBorder = bs_num_env - 1;
                    break;
                default:
                    middleBorder = bs_pointer - 1;
                    break;
            };
            break;
        case FIXVAR:
        case VARVAR:
            switch (bs_pointer)
            {
                case 0:
                case 1:
                    middleBorder = bs_num_env - 1;
                    break;
                default:
                    middleBorder = bs_num_env + 1 - bs_pointer;
                    break;
            };
            break;
    };


    tQ[0] = tE[0];
    if (bs_num_env > 1)
    {
        tQ[1] = tE[middleBorder];
        tQ[2] = tE[bs_num_env];
        bs_num_noise = 2;
    }
    else
    {
        tQ[1] = tE[bs_num_env];
        bs_num_noise = 1;
    }

    /*
     *  Check consistency on freq bands
     */

    if ((tE[bs_num_env] < tE[0]) || (tE[0] < 0))
    {
        err = SBRDEC_INVALID_BITSTREAM;
    }


    switch (frameClass)
    {
        case  FIXFIX:
            lA = -1;
            break;
        case VARFIX:
            switch (bs_pointer)
            {
                case 0:
                case 1:
                    lA = -1;
                    break;
                default:
                    lA = bs_pointer - 1;
                    break;
            };
            break;
        case FIXVAR:
        case VARVAR:
            switch (bs_pointer)
            {
                case 0:
                    lA = - 1;
                    break;
                default:
                    lA = bs_num_env + 1 - bs_pointer;
                    break;
            };
            break;
    };

    /*
     * Build the frameInfo vector...
     */

    v_frame_info[0] = bs_num_env;   /* Number of envelopes*/
    pv_memcpy(v_frame_info + 1, tE, (bs_num_env + 1)*sizeof(Int32));    /* time borders*/
    /* frequency resolution */
    pv_memcpy(v_frame_info + 1 + bs_num_env + 1, f, bs_num_env*sizeof(Int32));

    temp = (1 + bs_num_env) << 1;
    v_frame_info[temp] = lA;                     /* transient envelope*/
    v_frame_info[temp + 1] = bs_num_noise;       /* Number of noise envelopes */
    /* noise borders */
    pv_memcpy(v_frame_info + temp + 2, tQ, (bs_num_noise + 1)*sizeof(Int32));


    return (err);

}
Ejemplo n.º 5
0
SBR_ERROR sbr_get_cpe(SBR_FRAME_DATA * hFrameDataLeft,
                      SBR_FRAME_DATA * hFrameDataRight,
                      BIT_BUFFER  * hBitBuf)
{
    Int32 i;
    Int32 bits;
    SBR_ERROR err =  SBRDEC_OK;

    /* reserved bits */
    bits = buf_getbits(hBitBuf, SI_SBR_RESERVED_PRESENT);

    if (bits)
    {
        buf_getbits(hBitBuf, SI_SBR_RESERVED_BITS_DATA);
        buf_getbits(hBitBuf, SI_SBR_RESERVED_BITS_DATA);
    }

    /* Read coupling flag */
    bits = buf_getbits(hBitBuf, SI_SBR_COUPLING_BITS);

    if (bits)
    {
        hFrameDataLeft->coupling = COUPLING_LEVEL;
        hFrameDataRight->coupling = COUPLING_BAL;
    }
    else
    {
        hFrameDataLeft->coupling = COUPLING_OFF;
        hFrameDataRight->coupling = COUPLING_OFF;
    }


    err = extractFrameInfo(hBitBuf, hFrameDataLeft);

    if (err != SBRDEC_OK)
    {
        return err;
    }

    if (hFrameDataLeft->coupling)
    {

        pv_memcpy(hFrameDataRight->frameInfo,
                  hFrameDataLeft->frameInfo,
                  LENGTH_FRAME_INFO * sizeof(Int32));

        hFrameDataRight->nNoiseFloorEnvelopes = hFrameDataLeft->nNoiseFloorEnvelopes;
        hFrameDataRight->frameClass = hFrameDataLeft->frameClass;


        sbr_get_dir_control_data(hFrameDataLeft, hBitBuf);
        sbr_get_dir_control_data(hFrameDataRight, hBitBuf);

        for (i = 0; i < hFrameDataLeft->nNfb; i++)
        {
            hFrameDataLeft->sbr_invf_mode_prev[i]  = hFrameDataLeft->sbr_invf_mode[i];
            hFrameDataRight->sbr_invf_mode_prev[i] = hFrameDataRight->sbr_invf_mode[i];

            hFrameDataLeft->sbr_invf_mode[i]  = (INVF_MODE) buf_getbits(hBitBuf, SI_SBR_INVF_MODE_BITS);
            hFrameDataRight->sbr_invf_mode[i] = hFrameDataLeft->sbr_invf_mode[i];
        }

        sbr_get_envelope(hFrameDataLeft, hBitBuf);
        sbr_get_noise_floor_data(hFrameDataLeft, hBitBuf);
        sbr_get_envelope(hFrameDataRight, hBitBuf);

    }
    else
    {
        err = extractFrameInfo(hBitBuf, hFrameDataRight);

        if (err != SBRDEC_OK)
        {
            return err;
        }


        sbr_get_dir_control_data(hFrameDataLeft,  hBitBuf);
        sbr_get_dir_control_data(hFrameDataRight, hBitBuf);

        for (i = 0; i <  hFrameDataLeft->nNfb; i++)
        {
            hFrameDataLeft->sbr_invf_mode_prev[i]  = hFrameDataLeft->sbr_invf_mode[i];
            hFrameDataLeft->sbr_invf_mode[i]  =
                (INVF_MODE) buf_getbits(hBitBuf, SI_SBR_INVF_MODE_BITS);
        }

        for (i = 0; i <  hFrameDataRight->nNfb; i++)
        {
            hFrameDataRight->sbr_invf_mode_prev[i] = hFrameDataRight->sbr_invf_mode[i];

            hFrameDataRight->sbr_invf_mode[i] =
                (INVF_MODE) buf_getbits(hBitBuf, SI_SBR_INVF_MODE_BITS);
        }
        sbr_get_envelope(hFrameDataLeft,  hBitBuf);
        sbr_get_envelope(hFrameDataRight, hBitBuf);

        sbr_get_noise_floor_data(hFrameDataLeft,  hBitBuf);

    }

    sbr_get_noise_floor_data(hFrameDataRight, hBitBuf);

    pv_memset((void *)hFrameDataLeft->addHarmonics,
              0,
              hFrameDataLeft->nSfb[HI]*sizeof(Int32));

    pv_memset((void *)hFrameDataRight->addHarmonics,
              0,
              hFrameDataRight->nSfb[HI]*sizeof(Int32));

    sbr_get_additional_data(hFrameDataLeft, hBitBuf);
    sbr_get_additional_data(hFrameDataRight, hBitBuf);

    sbr_extract_extended_data(hBitBuf
// 2010.01.26 : 
// in order to detect ps tag in adts/adif but decoding it
// we remove this definition
////#ifdef PARAMETRICSTEREO
                              , NULL
////#endif
                             );

    return SBRDEC_OK;

}
Ejemplo n.º 6
0
SBR_HEADER_STATUS sbr_get_header_data(SBR_HEADER_DATA   * h_sbr_header,
                                      BIT_BUFFER          * hBitBuf,
                                      SBR_SYNC_STATE     syncState)
{
    SBR_HEADER_DATA lastHeader;
    Int32 headerExtra1, headerExtra2;


    /* Copy header to temporary header */
    if (syncState == SBR_ACTIVE)
    {
        pv_memcpy(&lastHeader, h_sbr_header, sizeof(SBR_HEADER_DATA));
    }
    else
    {
        pv_memset((void *)&lastHeader, 0, sizeof(SBR_HEADER_DATA));
    }


    /* Read new header from bitstream */
    h_sbr_header->ampResolution   = buf_getbits(hBitBuf, SI_SBR_AMP_RES_BITS);
    h_sbr_header->startFreq       = buf_getbits(hBitBuf, SI_SBR_START_FREQ_BITS);
    h_sbr_header->stopFreq        = buf_getbits(hBitBuf, SI_SBR_STOP_FREQ_BITS);
    h_sbr_header->xover_band      = buf_getbits(hBitBuf, SI_SBR_XOVER_BAND_BITS);

    buf_getbits(hBitBuf, SI_SBR_RESERVED_BITS_HDR);

    headerExtra1    = buf_getbits(hBitBuf, SI_SBR_HEADER_EXTRA_1_BITS);
    headerExtra2    = buf_getbits(hBitBuf, SI_SBR_HEADER_EXTRA_2_BITS);

    /* handle extra header information */
    if (headerExtra1)
    {
        h_sbr_header->freqScale   = buf_getbits(hBitBuf, SI_SBR_FREQ_SCALE_BITS);
        h_sbr_header->alterScale  = buf_getbits(hBitBuf, SI_SBR_ALTER_SCALE_BITS);
        h_sbr_header->noise_bands = buf_getbits(hBitBuf, SI_SBR_NOISE_BANDS_BITS);
    }
    else
    { /* Set default values.*/
        h_sbr_header->freqScale   = SBR_FREQ_SCALE_DEFAULT;
        h_sbr_header->alterScale  = SBR_ALTER_SCALE_DEFAULT;
        h_sbr_header->noise_bands = SBR_NOISE_BANDS_DEFAULT;
    }


    if (headerExtra2)
    {
        h_sbr_header->limiterBands    = buf_getbits(hBitBuf, SI_SBR_LIMITER_BANDS_BITS);
        h_sbr_header->limiterGains    = buf_getbits(hBitBuf, SI_SBR_LIMITER_GAINS_BITS);
        h_sbr_header->interpolFreq    = buf_getbits(hBitBuf, SI_SBR_INTERPOL_FREQ_BITS);
        h_sbr_header->smoothingLength = buf_getbits(hBitBuf, SI_SBR_SMOOTHING_LENGTH_BITS);
    }
    else
    { /* Set default values.*/
        h_sbr_header->limiterBands    = SBR_LIMITER_BANDS_DEFAULT;
        h_sbr_header->limiterGains    = SBR_LIMITER_GAINS_DEFAULT;
        h_sbr_header->interpolFreq    = SBR_INTERPOL_FREQ_DEFAULT;
        h_sbr_header->smoothingLength = SBR_SMOOTHING_LENGTH_DEFAULT;
    }

    if (syncState == SBR_ACTIVE)
    {
        h_sbr_header->status = HEADER_OK;

        /* look for new settings */
        if (lastHeader.startFreq   != h_sbr_header->startFreq   ||
                lastHeader.stopFreq    != h_sbr_header->stopFreq    ||
                lastHeader.xover_band  != h_sbr_header->xover_band  ||
                lastHeader.freqScale   != h_sbr_header->freqScale   ||
                lastHeader.alterScale  != h_sbr_header->alterScale  ||
                lastHeader.noise_bands != h_sbr_header->noise_bands)
        {
            h_sbr_header->status = HEADER_RESET;
        }
    }
    else
    {
        h_sbr_header->status = HEADER_RESET;
    }

    return h_sbr_header->status;
}
void sbr_extract_extended_data(BIT_BUFFER * hBitBuf
#ifdef PARAMETRICSTEREO         /* Parametric Stereo Decoder */
                               , HANDLE_PS_DEC hParametricStereoDec
#endif
                              )
{
    Int32 extended_data;
    Int32 i;
    Int32 nBitsLeft;
    Int32 extension_id;

    extended_data = buf_get_1bit(hBitBuf);    /*  SI_SBR_EXTENDED_DATA_BITS  */

    if (extended_data)
    {
        Int32 cnt;

        cnt = buf_getbits(hBitBuf, SI_SBR_EXTENSION_SIZE_BITS);
        if (cnt == (1 << SI_SBR_EXTENSION_SIZE_BITS) - 1)
        {
            cnt += buf_getbits(hBitBuf, SI_SBR_EXTENSION_ESC_COUNT_BITS);
        }

        nBitsLeft = (cnt << 3);
        while (nBitsLeft > 7)
        {
            extension_id = buf_getbits(hBitBuf, SI_SBR_EXTENSION_ID_BITS);
            nBitsLeft -= SI_SBR_EXTENSION_ID_BITS;

            switch (extension_id)
            {
#ifdef HQ_SBR
#ifdef PARAMETRICSTEREO

                    /*
                     *  Parametric Coding supports the Transient, Sinusoidal, Noise, and
                     *  Parametric Stereo tools (MPEG4).
                     *  3GPP use aac+ hq along with ps for enhanced aac+
                     *  The PS tool uses complex-value QMF data, therefore can not be used
                     *  with low power version of aac+
                     */
                case EXTENSION_ID_PS_CODING:

                    if (hParametricStereoDec != NULL)
                    {
                        if (!hParametricStereoDec->psDetected)
                        {
                            /* parametric stereo detected */
                            hParametricStereoDec->psDetected = 1;
                        }

                        nBitsLeft -= ps_read_data(hParametricStereoDec,
                                                  hBitBuf,
                                                  nBitsLeft);

                    }

                    break;
#endif
#endif
                case 0:

                default:
                    /*   An unknown extension id causes the remaining extension data
                     *   to be skipped
                     */
                    cnt = nBitsLeft >> 3; /* number of remaining bytes */

                    for (i = 0; i < cnt; i++)
                    {
                        buf_getbits(hBitBuf, 8);
                    }

                    nBitsLeft -= (cnt << 3);
            }
        }
        /* read fill bits for byte alignment */
        buf_getbits(hBitBuf, nBitsLeft);
    }
}