📄 sbrside.c
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: sbrside.c,v 1.1.2.2 2005/05/24 20:34:40 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++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -