123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575 |
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: sbrside.c,v 1.2 2005/05/24 16:01:55 albertofloyd Exp $
- *
- * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file,
- * are subject to the current version of the RealNetworks Public
- * Source License (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the current version of the RealNetworks Community
- * Source License (the "RCSL") available at
- * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
- * will apply. You may also obtain the license terms directly from
- * RealNetworks. You may not use this file except in compliance with
- * the RPSL or, if you have a valid RCSL with RealNetworks applicable
- * to this file, the RCSL. Please see the applicable RPSL or RCSL for
- * the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the
- * portions it created.
- *
- * This file, and the files included with this file, is distributed
- * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
- * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
- * ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- /**************************************************************************************
- * Fixed-point HE-AAC decoder
- * Jon Recker (jrecker@real.com)
- * February 2005
- *
- * sbrside.c - functions for unpacking side info from SBR bitstream
- **************************************************************************************/
- #include "sbr.h"
- /**************************************************************************************
- * Function: GetSampRateIdx
- *
- * Description: get index of given sample rate
- *
- * Inputs: sample rate (in Hz)
- *
- * Outputs: none
- *
- * Return: index of sample rate (table 1.15 in 14496-3:2001(E))
- * -1 if sample rate not found in table
- **************************************************************************************/
- int GetSampRateIdx(int sampRate)
- {
- int idx;
- for (idx = 0; idx < NUM_SAMPLE_RATES; idx++) {
- if (sampRate == sampRateTab[idx])
- return idx;
- }
- return -1;
- }
- /**************************************************************************************
- * Function: UnpackSBRHeader
- *
- * Description: unpack SBR header (table 4.56)
- *
- * Inputs: BitStreamInfo struct pointing to start of SBR header
- *
- * Outputs: initialized SBRHeader struct for this SCE/CPE block
- *
- * Return: non-zero if frame reset is triggered, zero otherwise
- **************************************************************************************/
- int UnpackSBRHeader(BitStreamInfo *bsi, SBRHeader *sbrHdr)
- {
- SBRHeader sbrHdrPrev;
- /* save previous values so we know whether to reset decoder */
- sbrHdrPrev.startFreq = sbrHdr->startFreq;
- sbrHdrPrev.stopFreq = sbrHdr->stopFreq;
- sbrHdrPrev.freqScale = sbrHdr->freqScale;
- sbrHdrPrev.alterScale = sbrHdr->alterScale;
- sbrHdrPrev.crossOverBand = sbrHdr->crossOverBand;
- sbrHdrPrev.noiseBands = sbrHdr->noiseBands;
- sbrHdr->ampRes = GetBits(bsi, 1);
- sbrHdr->startFreq = GetBits(bsi, 4);
- sbrHdr->stopFreq = GetBits(bsi, 4);
- sbrHdr->crossOverBand = GetBits(bsi, 3);
- sbrHdr->resBitsHdr = GetBits(bsi, 2);
- sbrHdr->hdrExtra1 = GetBits(bsi, 1);
- sbrHdr->hdrExtra2 = GetBits(bsi, 1);
- if (sbrHdr->hdrExtra1) {
- sbrHdr->freqScale = GetBits(bsi, 2);
- sbrHdr->alterScale = GetBits(bsi, 1);
- sbrHdr->noiseBands = GetBits(bsi, 2);
- } else {
- /* defaults */
- sbrHdr->freqScale = 2;
- sbrHdr->alterScale = 1;
- sbrHdr->noiseBands = 2;
- }
- if (sbrHdr->hdrExtra2) {
- sbrHdr->limiterBands = GetBits(bsi, 2);
- sbrHdr->limiterGains = GetBits(bsi, 2);
- sbrHdr->interpFreq = GetBits(bsi, 1);
- sbrHdr->smoothMode = GetBits(bsi, 1);
- } else {
- /* defaults */
- sbrHdr->limiterBands = 2;
- sbrHdr->limiterGains = 2;
- sbrHdr->interpFreq = 1;
- sbrHdr->smoothMode = 1;
- }
- sbrHdr->count++;
- /* if any of these have changed from previous frame, reset the SBR module */
- if (sbrHdr->startFreq != sbrHdrPrev.startFreq || sbrHdr->stopFreq != sbrHdrPrev.stopFreq ||
- sbrHdr->freqScale != sbrHdrPrev.freqScale || sbrHdr->alterScale != sbrHdrPrev.alterScale ||
- sbrHdr->crossOverBand != sbrHdrPrev.crossOverBand || sbrHdr->noiseBands != sbrHdrPrev.noiseBands
- )
- return -1;
- else
- return 0;
- }
- /* cLog2[i] = ceil(log2(i)) (disregard i == 0) */
- static const unsigned char cLog2[9] = {0, 0, 1, 2, 2, 3, 3, 3, 3};
- /**************************************************************************************
- * Function: UnpackSBRGrid
- *
- * Description: unpack SBR grid (table 4.62)
- *
- * Inputs: BitStreamInfo struct pointing to start of SBR grid
- * initialized SBRHeader struct for this SCE/CPE block
- *
- * Outputs: initialized SBRGrid struct for this channel
- *
- * Return: none
- **************************************************************************************/
- static void UnpackSBRGrid(BitStreamInfo *bsi, SBRHeader *sbrHdr, SBRGrid *sbrGrid)
- {
- int numEnvRaw, env, rel, pBits, border, middleBorder=0;
- unsigned char relBordLead[MAX_NUM_ENV], relBordTrail[MAX_NUM_ENV];
- unsigned char relBorder0[3], relBorder1[3], relBorder[3];
- unsigned char numRelBorder0, numRelBorder1, numRelBorder, numRelLead=0, numRelTrail;
- unsigned char absBordLead=0, absBordTrail=0, absBorder;
-
- sbrGrid->ampResFrame = sbrHdr->ampRes;
- sbrGrid->frameClass = GetBits(bsi, 2);
- switch (sbrGrid->frameClass) {
- case SBR_GRID_FIXFIX:
- numEnvRaw = GetBits(bsi, 2);
- sbrGrid->numEnv = (1 << numEnvRaw);
- if (sbrGrid->numEnv == 1)
- sbrGrid->ampResFrame = 0;
- ASSERT(sbrGrid->numEnv == 1 || sbrGrid->numEnv == 2 || sbrGrid->numEnv == 4);
- sbrGrid->freqRes[0] = GetBits(bsi, 1);
- for (env = 1; env < sbrGrid->numEnv; env++)
- sbrGrid->freqRes[env] = sbrGrid->freqRes[0];
- absBordLead = 0;
- absBordTrail = NUM_TIME_SLOTS;
- numRelLead = sbrGrid->numEnv - 1;
- numRelTrail = 0;
- /* numEnv = 1, 2, or 4 */
- if (sbrGrid->numEnv == 1) border = NUM_TIME_SLOTS / 1;
- else if (sbrGrid->numEnv == 2) border = NUM_TIME_SLOTS / 2;
- else border = NUM_TIME_SLOTS / 4;
- for (rel = 0; rel < numRelLead; rel++)
- relBordLead[rel] = border;
- middleBorder = (sbrGrid->numEnv >> 1);
- break;
- case SBR_GRID_FIXVAR:
- absBorder = GetBits(bsi, 2) + NUM_TIME_SLOTS;
- numRelBorder = GetBits(bsi, 2);
- sbrGrid->numEnv = numRelBorder + 1;
- for (rel = 0; rel < numRelBorder; rel++)
- relBorder[rel] = 2*GetBits(bsi, 2) + 2;
- pBits = cLog2[sbrGrid->numEnv + 1];
- sbrGrid->pointer = GetBits(bsi, pBits);
- for (env = sbrGrid->numEnv - 1; env >= 0; env--)
- sbrGrid->freqRes[env] = GetBits(bsi, 1);
- absBordLead = 0;
- absBordTrail = absBorder;
- numRelLead = 0;
- numRelTrail = numRelBorder;
- for (rel = 0; rel < numRelTrail; rel++)
- relBordTrail[rel] = relBorder[rel];
- if (sbrGrid->pointer > 1) middleBorder = sbrGrid->numEnv + 1 - sbrGrid->pointer;
- else middleBorder = sbrGrid->numEnv - 1;
- break;
- case SBR_GRID_VARFIX:
- absBorder = GetBits(bsi, 2);
- numRelBorder = GetBits(bsi, 2);
- sbrGrid->numEnv = numRelBorder + 1;
- for (rel = 0; rel < numRelBorder; rel++)
- relBorder[rel] = 2*GetBits(bsi, 2) + 2;
- pBits = cLog2[sbrGrid->numEnv + 1];
- sbrGrid->pointer = GetBits(bsi, pBits);
- for (env = 0; env < sbrGrid->numEnv; env++)
- sbrGrid->freqRes[env] = GetBits(bsi, 1);
- absBordLead = absBorder;
- absBordTrail = NUM_TIME_SLOTS;
- numRelLead = numRelBorder;
- numRelTrail = 0;
- for (rel = 0; rel < numRelLead; rel++)
- relBordLead[rel] = relBorder[rel];
- if (sbrGrid->pointer == 0) middleBorder = 1;
- else if (sbrGrid->pointer == 1) middleBorder = sbrGrid->numEnv - 1;
- else middleBorder = sbrGrid->pointer - 1;
- break;
- case SBR_GRID_VARVAR:
- absBordLead = GetBits(bsi, 2); /* absBorder0 */
- absBordTrail = GetBits(bsi, 2) + NUM_TIME_SLOTS; /* absBorder1 */
- numRelBorder0 = GetBits(bsi, 2);
- numRelBorder1 = GetBits(bsi, 2);
- sbrGrid->numEnv = numRelBorder0 + numRelBorder1 + 1;
- ASSERT(sbrGrid->numEnv <= 5);
- for (rel = 0; rel < numRelBorder0; rel++)
- relBorder0[rel] = 2*GetBits(bsi, 2) + 2;
- for (rel = 0; rel < numRelBorder1; rel++)
- relBorder1[rel] = 2*GetBits(bsi, 2) + 2;
- pBits = cLog2[numRelBorder0 + numRelBorder1 + 2];
- sbrGrid->pointer = GetBits(bsi, pBits);
- for (env = 0; env < sbrGrid->numEnv; env++)
- sbrGrid->freqRes[env] = GetBits(bsi, 1);
- numRelLead = numRelBorder0;
- numRelTrail = numRelBorder1;
- for (rel = 0; rel < numRelLead; rel++)
- relBordLead[rel] = relBorder0[rel];
- for (rel = 0; rel < numRelTrail; rel++)
- relBordTrail[rel] = relBorder1[rel];
- if (sbrGrid->pointer > 1) middleBorder = sbrGrid->numEnv + 1 - sbrGrid->pointer;
- else middleBorder = sbrGrid->numEnv - 1;
- break;
- }
- /* build time border vector */
- sbrGrid->envTimeBorder[0] = absBordLead * SAMPLES_PER_SLOT;
- rel = 0;
- border = absBordLead;
- for (env = 1; env <= numRelLead; env++) {
- border += relBordLead[rel++];
- sbrGrid->envTimeBorder[env] = border * SAMPLES_PER_SLOT;
- }
- rel = 0;
- border = absBordTrail;
- for (env = sbrGrid->numEnv - 1; env > numRelLead; env--) {
- border -= relBordTrail[rel++];
- sbrGrid->envTimeBorder[env] = border * SAMPLES_PER_SLOT;
- }
- sbrGrid->envTimeBorder[sbrGrid->numEnv] = absBordTrail * SAMPLES_PER_SLOT;
- if (sbrGrid->numEnv > 1) {
- sbrGrid->numNoiseFloors = 2;
- sbrGrid->noiseTimeBorder[0] = sbrGrid->envTimeBorder[0];
- sbrGrid->noiseTimeBorder[1] = sbrGrid->envTimeBorder[middleBorder];
- sbrGrid->noiseTimeBorder[2] = sbrGrid->envTimeBorder[sbrGrid->numEnv];
- } else {
- sbrGrid->numNoiseFloors = 1;
- sbrGrid->noiseTimeBorder[0] = sbrGrid->envTimeBorder[0];
- sbrGrid->noiseTimeBorder[1] = sbrGrid->envTimeBorder[1];
- }
- }
- /**************************************************************************************
- * Function: UnpackDeltaTimeFreq
- *
- * Description: unpack time/freq flags for delta coding of SBR envelopes (table 4.63)
- *
- * Inputs: BitStreamInfo struct pointing to start of dt/df flags
- * number of envelopes
- * number of noise floors
- *
- * Outputs: delta flags for envelope and noise floors
- *
- * Return: none
- **************************************************************************************/
- static void UnpackDeltaTimeFreq(BitStreamInfo *bsi, int numEnv, unsigned char *deltaFlagEnv,
- int numNoiseFloors, unsigned char *deltaFlagNoise)
- {
- int env, noiseFloor;
- for (env = 0; env < numEnv; env++)
- deltaFlagEnv[env] = GetBits(bsi, 1);
- for (noiseFloor = 0; noiseFloor < numNoiseFloors; noiseFloor++)
- deltaFlagNoise[noiseFloor] = GetBits(bsi, 1);
- }
- /**************************************************************************************
- * Function: UnpackInverseFilterMode
- *
- * Description: unpack invf flags for chirp factor calculation (table 4.64)
- *
- * Inputs: BitStreamInfo struct pointing to start of invf flags
- * number of noise floor bands
- *
- * Outputs: invf flags for noise floor bands
- *
- * Return: none
- **************************************************************************************/
- static void UnpackInverseFilterMode(BitStreamInfo *bsi, int numNoiseFloorBands, unsigned char *mode)
- {
- int n;
- for (n = 0; n < numNoiseFloorBands; n++)
- mode[n] = GetBits(bsi, 2);
- }
- /**************************************************************************************
- * Function: UnpackSinusoids
- *
- * Description: unpack sinusoid (harmonic) flags for each SBR subband (table 4.67)
- *
- * Inputs: BitStreamInfo struct pointing to start of sinusoid flags
- * number of high resolution SBR subbands (nHigh)
- *
- * Outputs: sinusoid flags for each SBR subband, zero-filled above nHigh
- *
- * Return: none
- **************************************************************************************/
- static void UnpackSinusoids(BitStreamInfo *bsi, int nHigh, int addHarmonicFlag, unsigned char *addHarmonic)
- {
- int n;
- n = 0;
- if (addHarmonicFlag) {
- for ( ; n < nHigh; n++)
- addHarmonic[n] = GetBits(bsi, 1);
- }
- /* zero out unused bands */
- for ( ; n < MAX_QMF_BANDS; n++)
- addHarmonic[n] = 0;
- }
- /**************************************************************************************
- * Function: CopyCouplingGrid
- *
- * Description: copy grid parameters from left to right for channel coupling
- *
- * Inputs: initialized SBRGrid struct for left channel
- *
- * Outputs: initialized SBRGrid struct for right channel
- *
- * Return: none
- **************************************************************************************/
- static void CopyCouplingGrid(SBRGrid *sbrGridLeft, SBRGrid *sbrGridRight)
- {
- int env, noiseFloor;
- sbrGridRight->frameClass = sbrGridLeft->frameClass;
- sbrGridRight->ampResFrame = sbrGridLeft->ampResFrame;
- sbrGridRight->pointer = sbrGridLeft->pointer;
- sbrGridRight->numEnv = sbrGridLeft->numEnv;
- for (env = 0; env < sbrGridLeft->numEnv; env++) {
- sbrGridRight->envTimeBorder[env] = sbrGridLeft->envTimeBorder[env];
- sbrGridRight->freqRes[env] = sbrGridLeft->freqRes[env];
- }
- sbrGridRight->envTimeBorder[env] = sbrGridLeft->envTimeBorder[env]; /* borders are [0, numEnv] inclusive */
- sbrGridRight->numNoiseFloors = sbrGridLeft->numNoiseFloors;
- for (noiseFloor = 0; noiseFloor <= sbrGridLeft->numNoiseFloors; noiseFloor++)
- sbrGridRight->noiseTimeBorder[noiseFloor] = sbrGridLeft->noiseTimeBorder[noiseFloor];
- /* numEnvPrev, numNoiseFloorsPrev, freqResPrev are updated in DecodeSBREnvelope() and DecodeSBRNoise() */
- }
- /**************************************************************************************
- * Function: CopyCouplingInverseFilterMode
- *
- * Description: copy invf flags from left to right for channel coupling
- *
- * Inputs: invf flags for left channel
- * number of noise floor bands
- *
- * Outputs: invf flags for right channel
- *
- * Return: none
- **************************************************************************************/
- static void CopyCouplingInverseFilterMode(int numNoiseFloorBands, unsigned char *modeLeft, unsigned char *modeRight)
- {
- int band;
- for (band = 0; band < numNoiseFloorBands; band++)
- modeRight[band] = modeLeft[band];
- }
- /**************************************************************************************
- * Function: UnpackSBRSingleChannel
- *
- * Description: unpack sideband info (grid, delta flags, invf flags, envelope and
- * noise floor configuration, sinusoids) for a single channel
- *
- * Inputs: BitStreamInfo struct pointing to start of sideband info
- * initialized PSInfoSBR struct (after parsing SBR header and building
- * frequency tables)
- * base output channel (range = [0, nChans-1])
- *
- * Outputs: updated PSInfoSBR struct (SBRGrid and SBRChan)
- *
- * Return: none
- **************************************************************************************/
- void UnpackSBRSingleChannel(BitStreamInfo *bsi, PSInfoSBR *psi, int chBase)
- {
- int bitsLeft;
- SBRHeader *sbrHdr = &(psi->sbrHdr[chBase]);
- SBRGrid *sbrGridL = &(psi->sbrGrid[chBase+0]);
- SBRFreq *sbrFreq = &(psi->sbrFreq[chBase]);
- SBRChan *sbrChanL = &(psi->sbrChan[chBase+0]);
- psi->dataExtra = GetBits(bsi, 1);
- if (psi->dataExtra)
- psi->resBitsData = GetBits(bsi, 4);
- UnpackSBRGrid(bsi, sbrHdr, sbrGridL);
- UnpackDeltaTimeFreq(bsi, sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors, sbrChanL->deltaFlagNoise);
- UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]);
- DecodeSBREnvelope(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0);
- DecodeSBRNoise(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0);
- sbrChanL->addHarmonicFlag[1] = GetBits(bsi, 1);
- UnpackSinusoids(bsi, sbrFreq->nHigh, sbrChanL->addHarmonicFlag[1], sbrChanL->addHarmonic[1]);
-
- psi->extendedDataPresent = GetBits(bsi, 1);
- if (psi->extendedDataPresent) {
- psi->extendedDataSize = GetBits(bsi, 4);
- if (psi->extendedDataSize == 15)
- psi->extendedDataSize += GetBits(bsi, 8);
- bitsLeft = 8 * psi->extendedDataSize;
- /* get ID, unpack extension info, do whatever is necessary with it... */
- while (bitsLeft > 0) {
- GetBits(bsi, 8);
- bitsLeft -= 8;
- }
- }
- }
- /**************************************************************************************
- * Function: UnpackSBRChannelPair
- *
- * Description: unpack sideband info (grid, delta flags, invf flags, envelope and
- * noise floor configuration, sinusoids) for a channel pair
- *
- * Inputs: BitStreamInfo struct pointing to start of sideband info
- * initialized PSInfoSBR struct (after parsing SBR header and building
- * frequency tables)
- * base output channel (range = [0, nChans-1])
- *
- * Outputs: updated PSInfoSBR struct (SBRGrid and SBRChan for both channels)
- *
- * Return: none
- **************************************************************************************/
- void UnpackSBRChannelPair(BitStreamInfo *bsi, PSInfoSBR *psi, int chBase)
- {
- int bitsLeft;
- SBRHeader *sbrHdr = &(psi->sbrHdr[chBase]);
- SBRGrid *sbrGridL = &(psi->sbrGrid[chBase+0]), *sbrGridR = &(psi->sbrGrid[chBase+1]);
- SBRFreq *sbrFreq = &(psi->sbrFreq[chBase]);
- SBRChan *sbrChanL = &(psi->sbrChan[chBase+0]), *sbrChanR = &(psi->sbrChan[chBase+1]);
- psi->dataExtra = GetBits(bsi, 1);
- if (psi->dataExtra) {
- psi->resBitsData = GetBits(bsi, 4);
- psi->resBitsData = GetBits(bsi, 4);
- }
- psi->couplingFlag = GetBits(bsi, 1);
- if (psi->couplingFlag) {
- UnpackSBRGrid(bsi, sbrHdr, sbrGridL);
- CopyCouplingGrid(sbrGridL, sbrGridR);
- UnpackDeltaTimeFreq(bsi, sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors, sbrChanL->deltaFlagNoise);
- UnpackDeltaTimeFreq(bsi, sbrGridR->numEnv, sbrChanR->deltaFlagEnv, sbrGridR->numNoiseFloors, sbrChanR->deltaFlagNoise);
- UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]);
- CopyCouplingInverseFilterMode(sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1], sbrChanR->invfMode[1]);
-
- DecodeSBREnvelope(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0);
- DecodeSBRNoise(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0);
- DecodeSBREnvelope(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1);
- DecodeSBRNoise(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1);
- /* pass RIGHT sbrChan struct */
- UncoupleSBREnvelope(psi, sbrGridL, sbrFreq, sbrChanR);
- UncoupleSBRNoise(psi, sbrGridL, sbrFreq, sbrChanR);
- } else {
- UnpackSBRGrid(bsi, sbrHdr, sbrGridL);
- UnpackSBRGrid(bsi, sbrHdr, sbrGridR);
- UnpackDeltaTimeFreq(bsi, sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors, sbrChanL->deltaFlagNoise);
- UnpackDeltaTimeFreq(bsi, sbrGridR->numEnv, sbrChanR->deltaFlagEnv, sbrGridR->numNoiseFloors, sbrChanR->deltaFlagNoise);
- UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]);
- UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanR->invfMode[1]);
- DecodeSBREnvelope(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0);
- DecodeSBREnvelope(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1);
- DecodeSBRNoise(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0);
- DecodeSBRNoise(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1);
- }
- sbrChanL->addHarmonicFlag[1] = GetBits(bsi, 1);
- UnpackSinusoids(bsi, sbrFreq->nHigh, sbrChanL->addHarmonicFlag[1], sbrChanL->addHarmonic[1]);
- sbrChanR->addHarmonicFlag[1] = GetBits(bsi, 1);
- UnpackSinusoids(bsi, sbrFreq->nHigh, sbrChanR->addHarmonicFlag[1], sbrChanR->addHarmonic[1]);
- psi->extendedDataPresent = GetBits(bsi, 1);
- if (psi->extendedDataPresent) {
- psi->extendedDataSize = GetBits(bsi, 4);
- if (psi->extendedDataSize == 15)
- psi->extendedDataSize += GetBits(bsi, 8);
- bitsLeft = 8 * psi->extendedDataSize;
- /* get ID, unpack extension info, do whatever is necessary with it... */
- while (bitsLeft > 0) {
- GetBits(bsi, 8);
- bitsLeft -= 8;
- }
- }
- }
|