コード例 #1
0
void get_dse(
    Char    *DataStreamBytes,
    BITS    *pInputStream)
{
    Int i;
    Int data_byte_align_flag;
    UInt count;
    Int esc_count;
    Char    *pDataStreamBytes;

    pDataStreamBytes = DataStreamBytes;

    /*
     *  Get element instance tag  ( 4 bits)
     *  ( max of 16 per raw data block)
     */
    get9_n_lessbits(LEN_TAG, pInputStream);

    /*
     *  get data_byte_align_flag ( 1 bit0 to see if byte alignment is
     *  performed within the DSE
     */
    data_byte_align_flag = get1bits(pInputStream);

    /*
     *  get count ( 8 bits)
     */
    count =  get9_n_lessbits(LEN_D_CNT, pInputStream);

    /*
     *  if count == 255, its value it is incremented  by a
     *  second 8 bit value, esc_count. This final value represents
     *  the number of bytes in the DSE
     */
    if (count == (1 << LEN_D_CNT) - 1)
    {
        esc_count = (Int)get9_n_lessbits(LEN_D_ESC, pInputStream);  /* 8 bits */
        count +=  esc_count;
    }

    /*
     *  Align if flag is set
     */
    if (data_byte_align_flag)
    {
        byte_align(pInputStream);
    }

    for (i = count; i != 0; i--)
    {
        *(pDataStreamBytes++) = (Char) get9_n_lessbits(
                                    LEN_BYTE,
                                    pInputStream);
    }

    return;

} /* end get_dse */
コード例 #2
0
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
void get_ele_list(
    EleList     *pElementList,
    BITS        *pInputStream,
    const Bool   enableCPE)
{
    Int index;
    Int *pEleIsCPE;
    Int *pEleTag;

    pEleIsCPE = &pElementList->ele_is_cpe[0];
    pEleTag   = &pElementList->ele_tag[0];

    for (index = pElementList->num_ele; index > 0; index--)
    {
        if (enableCPE != FALSE)
        {
            *pEleIsCPE++ = get1bits(/*LEN_ELE_IS_CPE, */pInputStream);
        }
        else
        {
            *pEleIsCPE++ = FALSE;
        }

        *pEleTag++ = get9_n_lessbits(LEN_TAG, pInputStream);

    } /* end for (index) */

    return;

} /* end get_ele_list */
void get_sbr_bitstream(SBRBITSTREAM *sbrBitStream, BITS *pInputStream)
{
    /*----------------------------------------------------------------------------
    ; Define all local variables
    ----------------------------------------------------------------------------*/

    Int32 count;
    Int32 esc_count;
    Int32 Extention_Type;
    Int32 i;

    count = get9_n_lessbits(LEN_F_CNT, pInputStream);
    if (count == 15)
    {
        esc_count = get9_n_lessbits(LEN_F_ESC, pInputStream);
        count = esc_count + 14;
    }



    Extention_Type = get9_n_lessbits(LEN_F_CNT, pInputStream);


    if (((Extention_Type == SBR_EXTENSION) || (Extention_Type == SBR_EXTENSION_CRC))
            && (count < MAXSBRBYTES) && (count) && (sbrBitStream->NrElements < MAXNRELEMENTS))
    {

        sbrBitStream->sbrElement[sbrBitStream->NrElements].ExtensionType = Extention_Type;
        sbrBitStream->sbrElement[sbrBitStream->NrElements].Payload       = count;
        sbrBitStream->sbrElement[sbrBitStream->NrElements].Data[0]       = (UChar) get9_n_lessbits(LEN_F_CNT, pInputStream);
        for (i = 1 ; i < count ; i++)
        {
            sbrBitStream->sbrElement[sbrBitStream->NrElements].Data[i] = (UChar) get9_n_lessbits(8, pInputStream);
        }

        sbrBitStream->NrElements += 1;

    }
    else
    {
        pInputStream->usedBits += (count - 1) * LEN_BYTE;
        pInputStream->usedBits += 4;        /* compenste for LEN_F_CNT (=4) bits read for Extention_Type */

    }
}
コード例 #4
0
ファイル: getmask.cpp プロジェクト: 0-t/android_frameworks_av
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
Int getmask(
    FrameInfo   *pFrameInfo,
    BITS        *pInputStream,
    Int         group[],
    Int         max_sfb,
    Int         mask[])
{

    Int     win; /* window index */
    Int     sfb;
    Int     mask_present;
    Int    *pMask;
    Int    *pGroup;
    Int     nwin;
    Int     nCall;
    Int     nToDo;
    UInt32  tempMask;
    UInt32  bitmask;

    pMask  = mask;
    pGroup = group;

    mask_present =
        get9_n_lessbits(
            LEN_MASK_PRES,
            pInputStream);

    switch (mask_present)
    {
        case(MASK_NOT_PRESENT):
            /* special EXTENDED_MS_MASK cases */
            /* no ms at all */
            break;

        case(MASK_ALL_FRAME):
            /* MS for whole spectrum on, mask bits set to 1 */
            nwin = pFrameInfo->num_win;
            for (win = 0; win < nwin; win = *(pGroup++))
            {
                for (sfb = pFrameInfo->sfb_per_win[win]; sfb > 0; sfb--)
                {
                    *(pMask++) = 1; /* cannot use memset for Int type */
                }

            }

            break;

        case(MASK_FROM_BITSTREAM):
            /* MS_mask_present==1, get mask information*/
            nwin = pFrameInfo->num_win;
            for (win = 0; win < nwin; win = *(pGroup++))
            {
                /*
                 * the following code is equivalent to
                 *
                 * for(sfb = max_sfb; sfb > 0; sfb--)
                 * {
                 *   *(pMask++) =
                 *       getbits(
                 *           LEN_MASK,
                 *           pInputStream);
                 * }
                 *
                 * in order to save the calls to getbits, the above
                 * for-loop is broken into two parts
                 */

                nToDo = max_sfb;

                while (nToDo > 0)
                {
                    nCall = nToDo;

                    if (nCall > MAX_GETBITS)
                    {
                        nCall = MAX_GETBITS;
                    }

                    tempMask =
                        getbits(
                            nCall,
                            pInputStream);

                    bitmask = (UInt32) 1 << (nCall - 1);
                    for (sfb = nCall; sfb > 0; sfb--)
                    {
                        *(pMask++) = (Int)((tempMask & bitmask) >> (sfb - 1));
                        bitmask >>= 1;
                    }

                    nToDo -= nCall;
                }

                /*
                 * set remaining sfbs to zero
                 * re-use nCall to save one variable on stack
                 */

                nCall = pFrameInfo->sfb_per_win[win] - max_sfb;


                if (nCall >= 0)
                {
                    pv_memset(pMask,
                              0,
                              nCall*sizeof(*pMask));

                    pMask += nCall;
                }
                else
                {
                    mask_present = MASK_ERROR;
                    break;
                }


            } /* for (win) */

            break;

        default:
            /* error */
            break;

    } /* switch (mask_present) */

    return mask_present;

} /* getmask */
コード例 #5
0
ファイル: lt_decode.c プロジェクト: drashti304/TizenRT
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
void lt_decode(
    const WINDOW_SEQUENCE  win_type,
    BITS            *pInputStream,
    const Int              max_sfb,
    LT_PRED_STATUS  *pLt_pred)
{
    Int wnd_num;
    Int k;
    Int last_band;
    Int prev_subblock;
    Int prev_subblock_nonzero;
    Int temp_reg;

    Bool *pWinPredictionUsed = pLt_pred->win_prediction_used;
    Bool *pSfbPredictionUsed = pLt_pred->sfb_prediction_used;
    Int  *pTempPtr;
    Int  *pDelay = pLt_pred->delay;

    pDelay[0] = (Int) get17_n_lessbits(
                    LEN_LTP_LAG,  /* 11 bits */
                    pInputStream);

    pLt_pred->weight_index  = (Int) get9_n_lessbits(
                                  LEN_LTP_COEF, /*  3 bits */
                                  pInputStream);

    last_band = max_sfb;

    if (win_type != EIGHT_SHORT_SEQUENCE)
    {

        /* last_band = min(MAX_LT_PRED_LONG_SFB, max_sfb) MAX_SCFAC_BANDS */
        if (last_band > MAX_LT_PRED_LONG_SFB)
        {
            last_band = MAX_LT_PRED_LONG_SFB;
        }

        for (k = last_band; k > 0; k--)
        {
            *(pSfbPredictionUsed++) = (Int) get1bits(pInputStream);
        }

        /*
         * This is not a call to memset, because
         * (max_sfb - last_band) should typically be a small value.
         */
        for (k = (max_sfb - last_band); k > 0; k--)
        {
            *(pSfbPredictionUsed++) = FALSE;
        }
    }
    else /* (win_type == EIGHT_SHORT_SEQUENCE) */
    {
        /* last_band = min(MAX_LT_PRED_SHORT_SFB, max_sfb) */

        if (last_band > MAX_LT_PRED_SHORT_SFB)
        {
            last_band = MAX_LT_PRED_SHORT_SFB;
        }

        /*
         * The following two coding constructs are equivalent...
         *
         *  first_time == 1
         *  for (wnd_num=NUM_SHORT_WINDOWS; wnd_num > 0; wnd_num--)
         *  {
         *     if (condition)
         *     {
         *       if (first_time == 1)
         *       {
         *           CODE SECTION A
         *           first_time = 0;
         *       }
         *       else
         *       {
         *           CODE SECTION B
         *       }
         *     }
         *  }
         *
         * -----------------------------------EQUIVALENT TO------------
         *
         *  wnd_num=NUM_SHORT_WINDOWS;
         *
         *  do
         *  {
         *     wnd_num--;
         *     if (condition)
         *     {
         *         CODE SECTION A
         *         break;
         *     }
         *  } while( wnd_num > 0)
         *
         *  while (wnd_num > 0)
         *  {
         *     if (condition)
         *     {
         *         CODE SECTION B
         *     }
         *     wnd_num--;
         *  }
         *
         */

        prev_subblock = pDelay[0];

        pTempPtr = &pSfbPredictionUsed[0];

        wnd_num = NUM_SHORT_WINDOWS;

        prev_subblock_nonzero = prev_subblock;
        prev_subblock += LTP_LAG_OFFSET;

        do
        {
            /*
             * Place decrement of wnd_num here, to insure
             * that the decrement occurs before the
             * break out of the do-while loop.
             */
            wnd_num--;

            temp_reg = (Int) get1bits(pInputStream);

            *(pWinPredictionUsed++) = temp_reg;

            if (temp_reg != FALSE)
            {
                *(pDelay++) = prev_subblock_nonzero;

                for (k = last_band; k > 0; k--)
                {
                    *(pTempPtr++) = TRUE;
                }
                for (k = (max_sfb - last_band); k > 0; k--)
                {
                    *(pTempPtr++) = FALSE;
                }
                break;

            } /* if(pWinPredictionUsed) */
            else
            {
                pDelay++;
                pTempPtr += max_sfb;
            }

        }
        while (wnd_num > 0);

        /*
         * This while loop picks up where the previous one left off.
         * Notice that the code functions differently inside the loop
         */

        while (wnd_num > 0)
        {
            temp_reg = (Int) get1bits(pInputStream);

            *(pWinPredictionUsed++) = temp_reg;

            if (temp_reg != FALSE)
            {
                temp_reg = (Int) get1bits(pInputStream);
                if (temp_reg != 0)
                {
                    temp_reg  = (Int) get9_n_lessbits(
                                    LEN_LTP_SHORT_LAG,
                                    pInputStream);

                    *(pDelay++) = prev_subblock - temp_reg;
                }
                else
                {
                    *(pDelay++) = prev_subblock_nonzero;
                }
                for (k = last_band; k > 0; k--)
                {
                    *(pTempPtr++) = TRUE;
                }
                for (k = (max_sfb - last_band); k > 0; k--)
                {
                    *(pTempPtr++) = FALSE;
                }

            } /* if (temp_reg) */
            else
            {
                pDelay++;
                pTempPtr += max_sfb;
            }

            wnd_num--;

        } /* while(wnd_num) */

    } /* else (win_type == EIGHT_SHORT_SEQUENCE) */

} /* lt_decode */
コード例 #6
0
Int get_adif_header(
    tDec_Int_File *pVars,
    ProgConfig    *pScratchPCE)
{
    Int          i;
    UInt32       temp;
    Int          numConfigElementsMinus1;
    Int          bitStreamType;
    UInt32       theIDFromFile;

    BITS        *pInputStream = &pVars->inputStream;
    ADIF_Header *pHeader = &pVars->scratch.adif_header;
    Int          status  = SUCCESS;

    /*
     * The ADIF_ID field is 32 bits long, one more than what getbits() can
     * do, so read the field in two parts. There is no point in saving the
     * string - it either matches or it does not. If it matches, it must
     * have been 'ADIF'
     */

    theIDFromFile = get17_n_lessbits((2 * LEN_BYTE), pInputStream);

    temp          = get17_n_lessbits((2 * LEN_BYTE), pInputStream);

    theIDFromFile = (theIDFromFile << (2 * LEN_BYTE)) | temp;


    if (theIDFromFile != ADIF_ID)
    {
        /*
         * Rewind the bit stream pointer so a search for ADTS header
         * can start at the beginning.
         */

        pInputStream->usedBits -= (4 * LEN_BYTE);

        /*
         * The constant in the next line needs to be updated when
         * error handling method is determined.
         */
        status = -1;
    }
    else
    {
        /*
         * To save space, the unused fields are read in, but not saved.
         */

        /* copyright string */
        temp =
            get1bits(/*                LEN_COPYRT_PRES,*/
                pInputStream);

        if (temp != FALSE)
        {
            /*
             * Read in and ignore the copyright string. If restoring
             * watch out for count down loop.
             */

            for (i = LEN_COPYRT_ID; i > 0; i--)
            {
                get9_n_lessbits(LEN_BYTE,
                                pInputStream);
            } /* end for */

            /*
             * Make sure to terminate the string with '\0' if restoring
             * the the copyright string.
             */

        } /* end if */

        /* Combine the original/copy and fields into one call */
        get9_n_lessbits(
            LEN_ORIG + LEN_HOME,
            pInputStream);

        bitStreamType =
            get1bits(/*                LEN_BS_TYPE,*/
                pInputStream);

        pHeader->bitrate =
            getbits(
                LEN_BIT_RATE,
                pInputStream);

        /*
         * Read in all the Program Configuration Elements.
         * For this library, only one of the up to 16 possible PCE's will be
         * saved. Since each PCE must be read, a temporary PCE structure is
         * used, and if that PCE is the one to use, it is copied into the
         * single PCE. This is done inside of get_prog_config()
         */

        numConfigElementsMinus1 =  get9_n_lessbits(LEN_NUM_PCE,
                                   pInputStream);

        for (i = numConfigElementsMinus1;
                (i >= 0) && (status == SUCCESS);
                i--)
        {
            /*
             * For ADIF contant bit rate streams, the _encoder_ buffer
             * fullness is transmitted. This version of an AAC decoder has
             * no use for this variable; yet it must be read in to move
             * the bitstream pointers.
             */

            if (bitStreamType == CONSTANT_RATE_BITSTREAM)
            {
                getbits(
                    LEN_ADIF_BF,
                    pInputStream);
            } /* end if */

            pVars->adif_test = 1;
            /* Get one program configuration element */
            status =
                get_prog_config(
                    pVars,
                    pScratchPCE);

#ifdef AAC_PLUS

            /*
             *  For implicit signalling, no hint that sbr or ps is used, so we need to
             *  check the sampling frequency of the aac content, if lesser or equal to
             *  24 KHz, by defualt upsample, otherwise, do nothing
             */
            if ((pVars->prog_config.sampling_rate_idx >= 6) && (pVars->aacPlusEnabled == true) &&
                    pVars->mc_info.audioObjectType == MP4AUDIO_AAC_LC)
            {
                pVars->mc_info.upsamplingFactor = 2;
                pVars->prog_config.sampling_rate_idx -= 3;
                pVars->mc_info.sbrPresentFlag = 1;
                pVars->sbrDecoderData.SbrChannel[0].syncState = UPSAMPLING;
                pVars->sbrDecoderData.SbrChannel[1].syncState = UPSAMPLING;
            }
#endif



        } /* end for */


    } /* end 'else' of --> if (theIDFromFile != ADIF_ID) */

    return status;

} /* end get_adif_header */
コード例 #7
0
Int get_prog_config(
    tDec_Int_File *pVars,
    ProgConfig    *pScratchPCE)
{
    Int    i;
    UInt   tag;
    Int    numChars;
    UInt   temp;
    Bool   flag;
    Int    status          = SUCCESS;
    BITS   *pInputStream   = &(pVars->inputStream);


    /*
     * The tag is used at the very end to see if this PCE is
     * the one to be used. Otherwise it does not need to be saved for the
     * the simple configurations to be used in this version of an AAC
     * decoder.
     *
     * All of the bits of this PCE must be read even if this PCE will not
     * be used. They are read into a temporary PCE, then later it is decided
     * whether to keep this PCE.
     *
     * To allow quick removal of the fields from the ProgConfig structure
     * that will probably not be used at a later date,
     * while still advancing the bitstream pointer,the return value of
     * getbits is saved into a temporary variable, then transfered to
     * the structure item.
     */
    tag = get9_n_lessbits(LEN_TAG, pInputStream);

    pScratchPCE->profile = get9_n_lessbits(LEN_PROFILE, pInputStream);

    pScratchPCE->sampling_rate_idx = get9_n_lessbits(LEN_SAMP_IDX, pInputStream);

    if (!pVars->adif_test && (pScratchPCE->sampling_rate_idx != pVars->prog_config.sampling_rate_idx))
    {
#ifdef AAC_PLUS
        /*
         *  PCE carries the baseline frequency, if SBR or PS are used, the frequencies will not match
         *  so check for this unique case, and let decoding continue if this is a redundant PCE
         */
        if ((pScratchPCE->sampling_rate_idx != (pVars->prog_config.sampling_rate_idx + 3)) ||
                (pVars->mc_info.upsamplingFactor != 2))
#endif
        {
            /* rewind the pointer as implicit channel configuration maybe the case */
            pInputStream->usedBits -= (LEN_TAG + LEN_PROFILE + LEN_SAMP_IDX);

            return (1); /*  mismatch cannot happen */
        }
    }


    /*
     * Retrieve the number of element lists for each of
     * front, side, back, lfe, data, and coupling.
     *
     * For two-channel stereo or mono, only the data in the front needs
     * to be saved. However, ALL fields need to be skipped over in some
     * fashion. Also, the number of elements needs to be temporarily saved
     * to call get_ele_list(). If that function was changed to pass in
     * the number of points to be read, the memory set aside inside the
     * ProgConfig structure could be removed.
     */

    /*
     * The next six function calls could be combined into one, then use
     * shifts and masks to retrieve the individual fields.
     */
    temp = get9_n_lessbits(LEN_NUM_ELE, pInputStream);

    pScratchPCE->front.num_ele = temp;

    /* Needed only to read in the element list. */
    temp = get9_n_lessbits(LEN_NUM_ELE, pInputStream);

    pScratchPCE->side.num_ele = temp;

    /* Needed only to read in the element list. */
    temp = get9_n_lessbits(LEN_NUM_ELE, pInputStream);

    pScratchPCE->back.num_ele = temp;

    /* Needed only to read in the element list. */
    temp = get9_n_lessbits(LEN_NUM_LFE, pInputStream);

    pScratchPCE->lfe.num_ele = temp;

    /* Needed only to read in the element list. */
    temp = get9_n_lessbits(LEN_NUM_DAT, pInputStream);
    pScratchPCE->data.num_ele = temp;

    /* Needed only to read in the element list. */
    temp = get9_n_lessbits(LEN_NUM_CCE, pInputStream);

    pScratchPCE->coupling.num_ele = temp;

    /*
     * Read in mix down data.
     *
     * Whether these fields can be removed and have proper operation
     * will be determined at a later date.
     */

    /* Read presence of mono_mix */
    flag = get1bits(pInputStream);/* LEN_MIX_PRES,*/

    pScratchPCE->mono_mix.present = flag;

    if (flag != FALSE)
    {
        temp = get9_n_lessbits(LEN_TAG, pInputStream);

        pScratchPCE->mono_mix.ele_tag = temp;

    } /* end if (flag != FALSE) */

    /* Read presence of stereo mix */
    flag = get1bits(pInputStream);   /* LEN_MIX_PRES,*/

    pScratchPCE->stereo_mix.present = flag;

    if (flag != FALSE)
    {
        temp = get9_n_lessbits(LEN_TAG, pInputStream);

        pScratchPCE->stereo_mix.ele_tag = temp;

    } /* end if (flag != FALSE) */

    /* Read presence of matrix mix */
    flag = get1bits(pInputStream);  /* LEN_MIX_PRES,*/

    pScratchPCE->matrix_mix.present = flag;

    if (flag != FALSE)
    {
        temp = get9_n_lessbits(LEN_MMIX_IDX, pInputStream);

        pScratchPCE->matrix_mix.ele_tag = temp;

        temp = get1bits(pInputStream);  /* LEN_PSUR_ENAB,*/

        pScratchPCE->matrix_mix.pseudo_enab = temp;

    } /* end if (flag != FALSE) */

    /*
     * Get each of the element lists. Only the front information will be
     * used for the PV decoder, but the usedBits field of pInputStream must
     * be advanced appropriately.
     *
     * This could be optimized by advancing the bit stream for the
     * elements that do not need to be read.
     */
    get_ele_list(&pScratchPCE->front,
                 pInputStream,
                 TRUE);

    get_ele_list(&pScratchPCE->side,
                 pInputStream,
                 TRUE);

    get_ele_list(&pScratchPCE->back,
                 pInputStream,
                 TRUE);

    get_ele_list(&pScratchPCE->lfe,
                 pInputStream,
                 FALSE);

    get_ele_list(&pScratchPCE->data,
                 pInputStream,
                 FALSE);

    get_ele_list(&pScratchPCE->coupling,
                 pInputStream,
                 TRUE);

    /*
     * The standard requests a byte alignment before reading in the
     * comment. This can be done because LEN_COMMENT_BYTES == 8.
     */
    byte_align(pInputStream);

    numChars = get9_n_lessbits(LEN_COMMENT_BYTES, pInputStream);

    /*
     * Ignore the comment - it requires 65 bytes to store (or worse on DSP).
     * If this field is restored, make sure to append a trailing '\0'
     */
    for (i = numChars; i > 0; i--)
    {
        pScratchPCE->comments[i] = (Char) get9_n_lessbits(LEN_BYTE,
                                   pInputStream);

    } /* end for */


    if (pVars->current_program < 0)
    {
        /*
         * If this is the first PCE, it becomes the current, regardless of
         * its tag number.
         */
        pVars->current_program = tag;

        pVars->mc_info.ch_info[0].tag = 0;

    } /* end if (pVars->current_program < 0) */


    if (tag == (UInt)pVars->current_program)
    {
        /*
         * This branch is reached under two conditions:
         * 1) This is the first PCE found, it was selected in the above if
         *    block. In all encoders found thus far, the tag value has been
         *    zero.
         * 2) A PCE has been sent by the encoder with a tag that matches the
         *    the first one sent. It will then be re-read. No encoder found
         *
         * Regardless, the temporary PCE will now be copied into the
         * the one official program configuration.
         */

        /*
         *  Keep adts setting in case of a redundant PCE (only applicable when
         *  using aac-lib own adts parser)
         */
        pScratchPCE->file_is_adts = pVars->prog_config.file_is_adts;
        pScratchPCE->headerless_frames = pVars->prog_config.headerless_frames;

        pv_memcpy(&pVars->prog_config,
                  pScratchPCE,
                  sizeof(ProgConfig));


        tag = 0;

        /*
         *  Check that dual-mono does not carry more than 2 tracks, otherwise flag an non-supported error
         */
        if ((pVars->prog_config.front.num_ele > 2) && !(pVars->prog_config.front.ele_is_cpe[tag]))
        {
            status = 1;
        }

        /*
         *  Check that stereo does not carry more than 1 track, otherwise flag an non-supported error
         */
        if ((pVars->prog_config.front.num_ele > 1) && (pVars->prog_config.front.ele_is_cpe[tag]))
        {
            status = 1;
        }



        if (!status)
        {

            /* enter configuration into MC_Info structure */
            status = set_mc_info(&pVars->mc_info,
                                 (tMP4AudioObjectType)(pVars->prog_config.profile + 1),
                                 pVars->prog_config.sampling_rate_idx,
                                 pVars->prog_config.front.ele_tag[tag],
                                 pVars->prog_config.front.ele_is_cpe[tag],
                                 pVars->winmap,
                                 pVars->SFBWidth128);

            if (pVars->mc_info.upsamplingFactor == 2)
            {
                /*
                 *  prog_config.sampling_rate_idx corresponds to the aac base layer,
                 *  if the upsampling factor is active, then the output frequency needs
                 *  to be adjusted accordingly
                 */
                pVars->prog_config.sampling_rate_idx -= 3;
            }

        }


    } /* end if (tag == pVars->current_program) */



    return (status);
}
コード例 #8
0
Int get_ics_info(
    const tMP4AudioObjectType  audioObjectType,
    BITS                      *pInputStream,
    const Bool                 common_window,
    WINDOW_SEQUENCE           *pWindowSequence,
    WINDOW_SHAPE              *pWindowShape,
    Int                        group[],
    Int                       *p_max_sfb,
    FrameInfo                 *p_winmap[],
    LT_PRED_STATUS            *pFirstLTPStatus,
    LT_PRED_STATUS            *pSecondLTPStatus)
{
    WINDOW_SEQUENCE       windowSequence;
    UInt                  temp;
    Bool                  predictor_data_present;
    UInt                   local_max_sfb;
    UInt                   allowed_max_sfb;
    Int                   status = SUCCESS;
    Bool                  first_ltp_data_present = FALSE;
    Bool                  second_ltp_data_present = FALSE;

    /*
     * The following three calls to getbits have been replaced with one
     * call for speed:
     *
     *                  getbits(LEN_ICS_RESERV, pInputStream);
     * windowSequence = getbits(LEN_WIN_SEQ, pInputStream);
     * *pWindowShape  = getbits(LEN_WIN_SH, pInputStream);
     *
     */

    temp =
        get9_n_lessbits(
            LEN_ICS_RESERV + LEN_WIN_SEQ + LEN_WIN_SH,
            pInputStream);


    windowSequence = (WINDOW_SEQUENCE)((temp >> LEN_WIN_SH) & ((0x1 << LEN_WIN_SEQ) - 1));

    *pWindowShape = (WINDOW_SHAPE)((temp) & ((0x1 << LEN_WIN_SH) - 1));

    /*
     * This pointer should not be NULL as long as the initialization code
     * has been run, so the test for NULL has been removed.
     */
    allowed_max_sfb = p_winmap[windowSequence]->sfb_per_win[0];

    if (windowSequence == EIGHT_SHORT_SEQUENCE)
    {
        local_max_sfb =  get9_n_lessbits(LEN_MAX_SFBS,
                                         pInputStream);

        getgroup(
            group,
            pInputStream);

        if (local_max_sfb > allowed_max_sfb)
        {
            status = 1;  /* ERROR CODE - needs to be updated */
        }

    } /* end of TRUE of if (windowSequence == EIGHT_SHORT_SEQUENCE) */
    else
    {
        /* There is only one group for long windows. */
        group[0] = 1;

        /*
         * The window is long, get the maximum scale factor bands,
         * and get long term prediction info.
         *
         * Reference [1] states that the audioObjectType is first tested,
         * then the predictor_data_present is read on either branch of the
         * if (audioObjectType == MP4AUDIO_LTP). Instead, this code combines
         * the two calls on both branches into one before the
         * if, and then in turn combines with another call to getbits, all
         * in the name of speed.
         *
         * This would be the individual calls, without checking the number
         * of scale factor bands:
         *
         *   local_max_sfb =
         *      (Int) getbits(
         *          LEN_MAX_SFBL,
         *           pInputStream);
         *
         *  if (audioObjectType == MP4AUDIO_LTP)
         *  {
         *        predictor_data_present =
         *           (Bool) getbits(
         *              LEN_PREDICTOR_DATA_PRESENT,
         *              pInputStream);
         *
         *     .....   (read LTP data)
         *
         *    }
         *    else
         *    {
         *
         *        predictor_data_present =
         *           (Bool) getbits(
         *              LEN_PREDICTOR_DATA_PRESENT,
         *              pInputStream);
         *
         *     .....   (its an error for this library)
         *     }
         */
        temp =
            get9_n_lessbits(
                LEN_MAX_SFBL + LEN_PREDICTOR_DATA_PRESENT,
                pInputStream);

        local_max_sfb = (Int)(temp >> LEN_PREDICTOR_DATA_PRESENT);

        predictor_data_present =
            (Bool)(temp & ((0x1 << LEN_PREDICTOR_DATA_PRESENT) - 1));

        if (local_max_sfb > allowed_max_sfb)
        {
            status = 1;  /* ERROR CODE - needs to be updated */
        }
        else if (audioObjectType == MP4AUDIO_LTP)
        {
            /*
             * Note that the predictor data bit has already been
             * read.
             */

            /*
             * If the object type is LTP, the predictor data is
             * LTP. If the object type is not LTP, the predictor data
             * is so called "frequency predictor data", which is not
             * supported by this implementation. Refer to (1)
             */
            if (predictor_data_present != FALSE)
            {
                first_ltp_data_present =
                    (Bool) get1bits(/*                        LEN_LTP_DATA_PRESENT,*/
                        pInputStream);

                if (first_ltp_data_present != FALSE)
                {
                    lt_decode(
                        windowSequence,
                        pInputStream,
                        local_max_sfb,
                        pFirstLTPStatus);
                }
                if (common_window != FALSE)
                {
                    second_ltp_data_present =
                        (Bool) get1bits(/*                            LEN_LTP_DATA_PRESENT,*/
                            pInputStream);

                    if (second_ltp_data_present != FALSE)
                    {
                        lt_decode(
                            windowSequence,
                            pInputStream,
                            local_max_sfb,
                            pSecondLTPStatus);
                    }
                } /* if (common_window != FALSE) */

            } /* if (predictor_data_present != FALSE) */

        } /* else if (audioObjectType == MP4AUDIO_LTP) */
        else
        {
            /*
             * Note that the predictor data bit has already been
             * read.
             */

            /*
             * The object type is not LTP. If there is data, its
             * frequency predictor data, not supported by this
             * implementation.
             */
            if (predictor_data_present != FALSE)
            {
                status = 1; /* ERROR CODE UPDATE LATER */
            } /* if (predictor_data_present != FALSE) */

        } /* end of "else" clause of if (audioObjectType == MP4AUDIO_LTP) */

    } /*  if (windowSequence == EIGHT_SHORT_SEQUENCE) [FALSE branch] */


    /*
     * Save all local copies.
     */
    pFirstLTPStatus->ltp_data_present = first_ltp_data_present;
    if (common_window != FALSE)
    {
        pSecondLTPStatus->ltp_data_present = second_ltp_data_present;
    }

    *p_max_sfb = local_max_sfb;

    *pWindowSequence = windowSequence;

    return (status);

}  /* get_ics_info */
コード例 #9
0
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
Int huffdecode(
    Int           id_syn_ele,
    BITS          *pInputStream,
    tDec_Int_File *pVars,
    tDec_Int_Chan *pChVars[])

{
    /*----------------------------------------------------------------------------
    ; Define all local variables
    ----------------------------------------------------------------------------*/
    Int      ch;
    Int      common_window;
    Int      hasmask;
    Int      status   = SUCCESS;
    Int      num_channels = 0;
    MC_Info  *pMcInfo;

    per_chan_share_w_fxpCoef *pChLeftShare;  /* Helper pointer */
    per_chan_share_w_fxpCoef *pChRightShare; /* Helper pointer */
    /*----------------------------------------------------------------------------
    ; Function body here
    ----------------------------------------------------------------------------*/

    get9_n_lessbits(
        LEN_TAG,
        pInputStream);

    /* suppose an un-supported id_syn_ele will never be passed */

    common_window = 0;

    if (id_syn_ele == ID_CPE)
    {
        common_window =
            get1bits(pInputStream);
    }

    pMcInfo = &pVars->mc_info;

    /*
     *  check if provided info (num of channels) on audio config,
     *  matches read bitstream data, if not, allow update only once.
     *  In almost all cases it should match.
     */
#if 0     
    if ((pMcInfo->ch_info[0].cpe != id_syn_ele))
    {
        if (pVars->mc_info.implicit_channeling)     /* check done only once */
        {
            pMcInfo->ch_info[0].cpe = id_syn_ele & 1; /*  collect info from bitstream
                                                     *  implicit_channeling flag is locked
                                                     *  after 1st frame, to avoid toggling
                                                     *  parameter in the middle of the clip
                                                     */
            pMcInfo->nch = (id_syn_ele & 1) + 1;     /* update number of channels */
        }
        else
        {
            status = 1; /* ERROR break if syntax error persist  */
        }
    }
#endif

    if (status == SUCCESS)
    {
        if (id_syn_ele == ID_SCE)
        {

            num_channels = 1;
            pVars->hasmask = 0;
        }
        else if (id_syn_ele == ID_CPE)
        {
            pChLeftShare = pChVars[LEFT]->pShareWfxpCoef;
            pChRightShare = pChVars[RIGHT]->pShareWfxpCoef;
            num_channels = 2;

            if (common_window != FALSE)
            {

                status = get_ics_info(
                             (tMP4AudioObjectType) pVars->mc_info.audioObjectType,
                             pInputStream,
                             (Bool)common_window,
                             (WINDOW_SEQUENCE *) & pChVars[LEFT]->wnd,
                             (WINDOW_SHAPE *) & pChVars[LEFT]->wnd_shape_this_bk,
                             pChLeftShare->group,
                             (Int *) & pChLeftShare->max_sfb,
                             pVars->winmap,
                             (LT_PRED_STATUS *) & pChLeftShare->lt_status,
                             (LT_PRED_STATUS *) & pChRightShare->lt_status);

                if (status == SUCCESS)
                {
                    /* copy left channel info to right channel */
                    pChVars[RIGHT]->wnd = pChVars[LEFT]->wnd;
                    pChVars[RIGHT]->wnd_shape_this_bk =
                        pChVars[LEFT]->wnd_shape_this_bk;
                    pChRightShare->max_sfb = pChLeftShare->max_sfb;
                    pv_memcpy(
                        pChRightShare->group,
                        pChLeftShare->group,
                        NSHORT*sizeof(pChLeftShare->group[0]));

                    hasmask = getmask(
                                  pVars->winmap[pChVars[LEFT]->wnd],
                                  pInputStream,
                                  pChLeftShare->group,
                                  pChLeftShare->max_sfb,
                                  pVars->mask);

                    if (hasmask == MASK_ERROR)
                    {
                        status = 1; /* ERROR code */
                    }
                    pVars->hasmask  = hasmask;

                } /* if (status == 0) */
            }
            else
            {
                pVars->hasmask  = 0;
            } /* if (common_window) */

        } /* if (id_syn_ele) */
        else if (id_syn_ele == ID_LFE)
        {
            num_channels = 1;
            pVars->hasmask = 0;
        } /* if (id_syn_ele) == ID_LFE */

    } /* if (status) */

    ch = 0;
    while ((ch < num_channels) && (status == SUCCESS))
    {
        pChLeftShare = pChVars[ch]->pShareWfxpCoef;

        status = getics(
                     pInputStream,
                     common_window,
                     pVars,
                     pChVars[ch],
                     pChLeftShare->group,
                     &pChLeftShare->max_sfb,
                     pChLeftShare->cb_map,
                     &pChLeftShare->tns,
                     pVars->winmap,
                     &pVars->share.a.pulseInfo,
                     pVars->share.a.sect);

        ch++;

    } /* while (ch) */

    /*----------------------------------------------------------------------------
    ; Return status
    ----------------------------------------------------------------------------*/

    return status;

} /* huffdecode */
コード例 #10
0
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
Int get_audio_specific_config(tDec_Int_File   * const pVars)
{

    UInt    temp;
    tMP4AudioObjectType     audioObjectType;
    //UInt32  sampling_rate;
    UInt    channel_config;
    UInt    syncExtensionType;
    UInt    extensionAudioObjectType = 0;
    UInt    extensionSamplingFrequencyIndex = 0;
    BITS   *pInputStream;
    Int     status;

    status = SUCCESS;

    pInputStream = &(pVars->inputStream);

    pVars->mc_info.upsamplingFactor = 1;   /*  default to regular AAC */

    temp =  get9_n_lessbits(LEN_OBJ_TYPE + LEN_SAMP_RATE_IDX,
                            pInputStream);

    /*
     * The following code can directly set the values of elements in
     * MC_Info, rather than first setting the values in pVars->prog_config
     * and then copy these values to MC_Info by calling set_mc_info.
     * In order to keep consistent with get_prog_config (ADIF) and
     * get_adts_header (ADTS), the code here is still copying
     * the info, and set the pVars->current_program = 0
     */

    /* AudioObjectType */
    audioObjectType = (tMP4AudioObjectType)((temp & 0x1f0) >> 4);

    pVars->mc_info.ExtendedAudioObjectType =  audioObjectType;   /* default */
    /* saving an audioObjectType into a profile field */
    /* pVars->prog_config.profile = audioObjectType; */

    /* sampling rate index */
    pVars->prog_config.sampling_rate_idx = temp & 0xf;

    if (pVars->prog_config.sampling_rate_idx > 0xb)
    {
        /*
         *  Only support 12 sampling frequencies from array samp_rate_info ( see sfb.cpp)
         *  7350 Hz (index 0xc) is not supported, the other indexes are reserved or escape
         */
        if (pVars->prog_config.sampling_rate_idx == 0xf) /* escape sequence */
        {
            /*
             * sampling rate not listed in Table 1.6.2,
             * this release does not support this
             */
            /*sampling_rate =  getbits( LEN_SAMP_RATE,
                                      pInputStream);*/
            getbits(LEN_SAMP_RATE, pInputStream); /* future use */
        }

        status = 1;
    }

    channel_config =  get9_n_lessbits(LEN_CHAN_CONFIG,
                                      pInputStream);

    if ((channel_config > 2) && (!pVars->aacConfigUtilityEnabled))
    {
        /*
         * AAC lib does not support more than two channels
         * signal error when in decoder mode
         * do not test when in utility mode
         */
        status = 1;

    }

    if (audioObjectType == MP4AUDIO_SBR || audioObjectType == MP4AUDIO_PS)
    {
        /* to disable explicit backward compatiblity check */
        pVars->mc_info.ExtendedAudioObjectType = MP4AUDIO_SBR;
        pVars->mc_info.sbrPresentFlag = 1;

        if (audioObjectType == MP4AUDIO_PS)
        {
            pVars->mc_info.psPresentFlag = 1;
            pVars->mc_info.ExtendedAudioObjectType = MP4AUDIO_PS;
        }

        extensionSamplingFrequencyIndex = /* extensionSamplingFrequencyIndex */
            get9_n_lessbits(LEN_SAMP_RATE_IDX,
                            pInputStream);
        if (extensionSamplingFrequencyIndex == 0x0f)
        {
            /*
             * sampling rate not listed in Table 1.6.2,
             * this release does not support this
                */
            /*sampling_rate = getbits( LEN_SAMP_RATE,
                                     pInputStream);*/
            getbits(LEN_SAMP_RATE, pInputStream);
        }

        audioObjectType = (tMP4AudioObjectType) get9_n_lessbits(LEN_OBJ_TYPE ,
                          pInputStream);
    }


    if ((/*(audioObjectType == MP4AUDIO_AAC_MAIN)     ||*/
                (audioObjectType == MP4AUDIO_AAC_LC)        ||
                /*(audioObjectType == MP4AUDIO_AAC_SSR)       ||*/
                (audioObjectType == MP4AUDIO_LTP)           /*||*/
                /*(audioObjectType == MP4AUDIO_AAC_SCALABLE)  ||*/
                /*(audioObjectType == MP4AUDIO_TWINVQ)*/) && (status == SUCCESS))
    {
        status = get_GA_specific_config(pVars,
                                        pInputStream,
                                        channel_config,
                                        audioObjectType);

        /*
         *  verify that Program config returned a supported audio object type
         */

        if ((pVars->mc_info.audioObjectType != MP4AUDIO_AAC_LC) &&
                (pVars->mc_info.audioObjectType != MP4AUDIO_LTP))
        {
            return 1;   /* status != SUCCESS invalid aot */
        }
    }
    else
    {
        return 1;   /* status != SUCCESS invalid aot or invalid parameter */
    }

    /*
     *  SBR tool explicit signaling ( backward compatible )
     */
    if (extensionAudioObjectType != MP4AUDIO_SBR)
    {
        syncExtensionType = (UInt)get17_n_lessbits(LEN_SYNC_EXTENSION_TYPE,
                            pInputStream);
		printf("%s(): syncExtensionType:%d\n", __FUNCTION__, syncExtensionType);
        if (syncExtensionType == 0x2b7)
        {
            extensionAudioObjectType = get9_n_lessbits( /* extensionAudioObjectType */
                                           LEN_OBJ_TYPE,
                                           pInputStream);

            if (extensionAudioObjectType == MP4AUDIO_SBR)
            {
				printf("%s(): extensionAudioObjectType is MP4AUDIO_SBR\n", __FUNCTION__);
                pVars->mc_info.sbrPresentFlag = get1bits(pInputStream);  /* sbrPresentFlag */
                if (pVars->mc_info.sbrPresentFlag == 1)
                {
					printf("%s(): sbrPresent\n", __FUNCTION__);
                    extensionSamplingFrequencyIndex =
                        get9_n_lessbits( /* extensionSamplingFrequencyIndex */
                            LEN_SAMP_RATE_IDX,
                            pInputStream);
                    if (pVars->aacPlusEnabled == true)
                    {
#ifdef AAC_PLUS
                        if (extensionSamplingFrequencyIndex < 3)
                        {
                            /*
                             *  Disable SBR/PS for any sampling freq. > 48 KHz
                             *  3GPP request support up to Level 2, == max AAC/SBR present
                             *  24/48 KHz
                             */
                            pVars->aacPlusEnabled = false;
							printf("%s(): diasable\n", __FUNCTION__);
                        }
                        else
                        {
                            pVars->mc_info.upsamplingFactor = (samp_rate_info[extensionSamplingFrequencyIndex].samp_rate >> 1) ==
                                                              samp_rate_info[pVars->prog_config.sampling_rate_idx].samp_rate ? 2 : 1;
							printf("%s(): upsamplingFactor : %d\n", __FUNCTION__, pVars->mc_info.upsamplingFactor);
                            if ((Int)extensionSamplingFrequencyIndex == pVars->prog_config.sampling_rate_idx)
                            {
                                /*
                                 *  Disable SBR decoding for any sbr-downsampled file whose SF is >= 24 KHz
                                 */
                                if (pVars->prog_config.sampling_rate_idx < 6)
                                {
                                    pVars->aacPlusEnabled = false;
									printf("%s(): diasable\n", __FUNCTION__);
                                }

                                pVars->mc_info.bDownSampledSbr = true;
                            }

                            pVars->prog_config.sampling_rate_idx = extensionSamplingFrequencyIndex;
                        }

#endif
                    }
					else printf("pVars->aacPlusEnabled is false\n");
コード例 #11
0
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
Int huffcb(
    SectInfo    *pSect,
    BITS        *pInputStream,
    Int         sectbits[],
    Int         tot_sfb,
    Int         sfb_per_win,
    Int         max_sfb)
{
    /*----------------------------------------------------------------------------
    ; Define all local variables
    ----------------------------------------------------------------------------*/

    Int   base;        /* section boundary */
    Int   sect_len_incr;
    Int   esc_val;     /* ESC of section length = 31(long), =7 (short) */
    Int     bits;        /* # of bits used to express esc_val */
    Int     num_sect;
    Int     active_sfb;
    Int   group_base;


    /*----------------------------------------------------------------------------
    ; Function body here
    ----------------------------------------------------------------------------*/

    bits       =  sectbits[0];     /* 3 for SHORT_WIN, 5 for LONG_WIN */
    esc_val    = (1 << bits) - 1;   /* ESC_value for section length */
    num_sect   =  0;
    base       =  0;
    group_base =  0;

    /* read until the end of one frame */
    while ((base < tot_sfb) && (num_sect < tot_sfb))
    {

        pSect->sect_cb  = get9_n_lessbits(
                              LEN_CB,
                              pInputStream); /* section codebook */

        sect_len_incr   = get9_n_lessbits(
                              bits,
                              pInputStream); /* length_incr */


        /* read until non-ESC value, see p55 reference 2 */
        while ((sect_len_incr == esc_val) && (base < tot_sfb))
        {
            base            +=  esc_val;

            sect_len_incr   = get9_n_lessbits(
                                  bits,
                                  pInputStream);
        }

        base      += sect_len_incr;
        pSect->sect_end  =  base; /* total # of sfb until current section */
        pSect++;
        num_sect++;

        /* active_sfb = base % sfb_per_win; */
        active_sfb = base - group_base;

        /*
         *  insert a zero section for regions above max_sfb for each group
         *  Make sure that active_sfb is also lesser than tot_sfb
         */

        if ((active_sfb == max_sfb) && (active_sfb < tot_sfb))
        {
            base      += (sfb_per_win - max_sfb);
            pSect->sect_cb   =   0; /* huffman codebook 0 */
            pSect->sect_end  =   base;
            num_sect++;
            pSect++;
            group_base = base;
        }
        else if (active_sfb > max_sfb)
        {
            /* within each group, the sections must delineate the sfb
             * from zero to max_sfb so that the 1st section within each
             * group starts at sfb0 and the last section ends at max_sfb
             * see p55 reference 2
             */
            break;
        }

    } /* while (base=0) */


    if (base != tot_sfb || num_sect > tot_sfb)
    {
        num_sect = 0;   /* error */
    }

    return num_sect;

} /* huffcb */
コード例 #12
0
/*----------------------------------------------------------------------------
; FUNCTION CODE
----------------------------------------------------------------------------*/
Int getics(
    Int             id_syn_ele,
    BITS            *pInputStream,
    Int             common_window,
    tDec_Int_File   *pVars,
    tDec_Int_Chan   *pChVars,
    Int             group[],
    Int             *pMax_sfb,
    Int             *pCodebookMap,
    TNS_frame_info  *pTnsFrameInfo,
    FrameInfo       **pWinMap,
    PulseInfo       *pPulseInfo,
    SectInfo        sect[])
{
    /*----------------------------------------------------------------------------
    ; Define all local variables
    ----------------------------------------------------------------------------*/
    Int     status = SUCCESS;

    Int     nsect = 0;
    Int     i;
    Int     cb;
    Int     sectWidth;
    Int     sectStart;
    Int     totSfb;
    Int     *pGroup;

    FrameInfo *pFrameInfo;

    Int     global_gain; /* originally passed in from huffdecode */
    Bool    present;

    /*----------------------------------------------------------------------------
    ; Function body here
    ----------------------------------------------------------------------------*/
    pGroup = group;

    /* read global gain from Input bitstream */
    global_gain = get9_n_lessbits(LEN_SCL_PCM, pInputStream);

    if (common_window == FALSE)
    {
        status = get_ics_info(pVars->mc_info.audioObjectType,
                              pInputStream,
                              common_window,
                              &pChVars->wnd,
                              &pChVars->wnd_shape_this_bk,
                              group,
                              pMax_sfb,
                              pWinMap,
                              &pChVars->pShareWfxpCoef->lt_status,
                              NULL);
    }

    pFrameInfo = pWinMap[pChVars->wnd];

    /* at least, number of window should be 1 or 8 */
    if ((pFrameInfo->num_win != 1) && (pFrameInfo->num_win != 8))
    {
        status = 1;
    }

    /* First, calculate total number of scalefactor bands
     * for this grouping. Then, decode section data
     */
    if (*pMax_sfb > 0)
    {

        /* calculate total number of sfb */
        i      = 0;
        totSfb = 0;

        do
        {
            totSfb++;

        }
        while (*pGroup++ < pFrameInfo->num_win);

        totSfb  *=  pFrameInfo->sfb_per_win[0];

        /* decode section data */
        nsect = huffcb(sect,
                       pInputStream,
                       pFrameInfo->sectbits,
                       totSfb,
                       pFrameInfo->sfb_per_win[0],
                       *pMax_sfb);

        if (nsect == 0)
        {
            status = 1;     /* decode section data error */

        }/* if (nsect) */

        /* generate "linear" description from section info
         * stored as codebook for each scalefactor band and group
         * when nsect == 0, for-loop does not execute
         */
        sectStart = 0;
        for (i = 0; i < nsect; i++)
        {
            cb  = sect[i].sect_cb;
            sectWidth =  sect[i].sect_end - sectStart;
            sectStart += sectWidth;

            while (sectWidth > 0)
            {
                *pCodebookMap++ = cb;   /* cannot use memset for Int */
                sectWidth--;
            }

        } /* for (i) */

    }
    else
    {
        /* set all sections with ZERO_HCB */
        pv_memset(pCodebookMap,
                  ZERO_HCB,
                  MAXBANDS*sizeof(*pCodebookMap));
        /*
                for (i=MAXBANDS; i>0; i--)
                {
                    *(pCodebookMap++) = ZERO_HCB;
                }
        */

    } /* if (*pMax_sfb) */

    /* calculate band offsets
     * (because of grouping and interleaving this cannot be
     * a constant: store it in pFrameInfo->frame_sfb_top)
     */
    if (pFrameInfo->islong == FALSE)
    {
        calc_gsfb_table(pFrameInfo, group);
    }

    /* decode scale factor data */
    if (status == SUCCESS)
    {
        status = hufffac(pFrameInfo,
                         pInputStream,
                         group,
                         nsect,
                         sect,
                         global_gain,
                         pChVars->pShareWfxpCoef->factors,
                         pVars->scratch.a.huffbook_used);

    } /* if (status) */

    /* noiseless coding */
    if (status == SUCCESS)
    {
        present = get1bits(pInputStream);

        pPulseInfo->pulse_data_present = present;

        if (present != FALSE)
        {
            if (pFrameInfo->islong == 1)
            {
                status = get_pulse_data(pPulseInfo,
                                        pInputStream);
            }
            else
            {
                /* CommonExit(1,"Pulse data not allowed for short blocks"); */
                status = 1;

            } /* if (pFrameInfo) */
        } /* if (present) */

    } /* if (status) */


    /* decode tns data */
    if (status == SUCCESS)
    {
        present = get1bits(pInputStream);

        pTnsFrameInfo->tns_data_present = present;

        if (present != FALSE)
        {
            get_tns(pChVars->pShareWfxpCoef->max_sfb,
                    pInputStream,
                    pChVars->wnd,
                    pFrameInfo,
                    &pVars->mc_info,
                    pTnsFrameInfo,
                    pVars->scratch.a.tns_decode_coef);
        }
        else
        {
            for (i = pFrameInfo->num_win - 1; i >= 0 ; i--)
            {
                pTnsFrameInfo->n_filt[i] = 0;
            }

        } /* if(present) */

    } /* if (status) */

    /* gain control */
    if (status == SUCCESS)
    {
        present =
            get1bits(pInputStream);

        if (present != FALSE)
        {
            /* CommonExit(1, "Gain control not implemented"); */
            status = 1;
        }
    } /* if (status) */

    if (status == SUCCESS)
    {
        /* Support Mono, Dual-Mono, or Stereo */
        if ((id_syn_ele == ID_SCE) || (id_syn_ele == ID_CPE))
        {
            status = huffspec_fxp(pFrameInfo,
                                  pInputStream,
                                  nsect,
                                  sect,
                                  pChVars->pShareWfxpCoef->factors,
                                  pChVars->fxpCoef,
                                  pVars->share.a.quantSpec,
                                  pVars->scratch.tmp_spec,
                                  pWinMap[ONLY_LONG_WINDOW],
                                  pPulseInfo,
                                  pChVars->pShareWfxpCoef->qFormat);
        }
    }

    /*----------------------------------------------------------------------------
    ; Return status
    ----------------------------------------------------------------------------*/

    return status;

} /* getics */