📄 sbrside.c
字号:
/* ***** BEGIN LICENSE BLOCK *****
*
* 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++];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -