mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-11 05:57:05 +03:00
big merge
This commit is contained in:
425
components/spotify/cspot/bell/libhelix-aac/decelmnt.c
Normal file
425
components/spotify/cspot/bell/libhelix-aac/decelmnt.c
Normal file
@@ -0,0 +1,425 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Source last modified: $Id: decelmnt.c,v 1.1 2005/02/26 01:47:34 jrecker 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
|
||||
*
|
||||
* decelmnt.c - syntactic element decoding
|
||||
**************************************************************************************/
|
||||
|
||||
#include "coder.h"
|
||||
|
||||
/**************************************************************************************
|
||||
* Function: DecodeSingleChannelElement
|
||||
*
|
||||
* Description: decode one SCE
|
||||
*
|
||||
* Inputs: BitStreamInfo struct pointing to start of SCE (14496-3, table 4.4.4)
|
||||
*
|
||||
* Outputs: updated element instance tag
|
||||
*
|
||||
* Return: 0 if successful, -1 if error
|
||||
*
|
||||
* Notes: doesn't decode individual channel stream (part of DecodeNoiselessData)
|
||||
**************************************************************************************/
|
||||
static int DecodeSingleChannelElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi)
|
||||
{
|
||||
/* validate pointers */
|
||||
if (!aacDecInfo || !aacDecInfo->psInfoBase)
|
||||
return -1;
|
||||
|
||||
/* read instance tag */
|
||||
aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
* Function: DecodeChannelPairElement
|
||||
*
|
||||
* Description: decode one CPE
|
||||
*
|
||||
* Inputs: BitStreamInfo struct pointing to start of CPE (14496-3, table 4.4.5)
|
||||
*
|
||||
* Outputs: updated element instance tag
|
||||
* updated commonWin
|
||||
* updated ICS info, if commonWin == 1
|
||||
* updated mid-side stereo info, if commonWin == 1
|
||||
*
|
||||
* Return: 0 if successful, -1 if error
|
||||
*
|
||||
* Notes: doesn't decode individual channel stream (part of DecodeNoiselessData)
|
||||
**************************************************************************************/
|
||||
static int DecodeChannelPairElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi)
|
||||
{
|
||||
int sfb, gp, maskOffset;
|
||||
unsigned char currBit, *maskPtr;
|
||||
PSInfoBase *psi;
|
||||
ICSInfo *icsInfo;
|
||||
|
||||
/* validate pointers */
|
||||
if (!aacDecInfo || !aacDecInfo->psInfoBase)
|
||||
return -1;
|
||||
psi = (PSInfoBase *)(aacDecInfo->psInfoBase);
|
||||
icsInfo = psi->icsInfo;
|
||||
|
||||
/* read instance tag */
|
||||
aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS);
|
||||
|
||||
/* read common window flag and mid-side info (if present)
|
||||
* store msMask bits in psi->msMaskBits[] as follows:
|
||||
* long blocks - pack bits for each SFB in range [0, maxSFB) starting with lsb of msMaskBits[0]
|
||||
* short blocks - pack bits for each SFB in range [0, maxSFB), for each group [0, 7]
|
||||
* msMaskPresent = 0 means no M/S coding
|
||||
* = 1 means psi->msMaskBits contains 1 bit per SFB to toggle M/S coding
|
||||
* = 2 means all SFB's are M/S coded (so psi->msMaskBits is not needed)
|
||||
*/
|
||||
psi->commonWin = GetBits(bsi, 1);
|
||||
if (psi->commonWin) {
|
||||
DecodeICSInfo(bsi, icsInfo, psi->sampRateIdx);
|
||||
psi->msMaskPresent = GetBits(bsi, 2);
|
||||
if (psi->msMaskPresent == 1) {
|
||||
maskPtr = psi->msMaskBits;
|
||||
*maskPtr = 0;
|
||||
maskOffset = 0;
|
||||
for (gp = 0; gp < icsInfo->numWinGroup; gp++) {
|
||||
for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) {
|
||||
currBit = (unsigned char)GetBits(bsi, 1);
|
||||
*maskPtr |= currBit << maskOffset;
|
||||
if (++maskOffset == 8) {
|
||||
maskPtr++;
|
||||
*maskPtr = 0;
|
||||
maskOffset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
* Function: DecodeLFEChannelElement
|
||||
*
|
||||
* Description: decode one LFE
|
||||
*
|
||||
* Inputs: BitStreamInfo struct pointing to start of LFE (14496-3, table 4.4.9)
|
||||
*
|
||||
* Outputs: updated element instance tag
|
||||
*
|
||||
* Return: 0 if successful, -1 if error
|
||||
*
|
||||
* Notes: doesn't decode individual channel stream (part of DecodeNoiselessData)
|
||||
**************************************************************************************/
|
||||
static int DecodeLFEChannelElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi)
|
||||
{
|
||||
/* validate pointers */
|
||||
if (!aacDecInfo || !aacDecInfo->psInfoBase)
|
||||
return -1;
|
||||
|
||||
/* read instance tag */
|
||||
aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
* Function: DecodeDataStreamElement
|
||||
*
|
||||
* Description: decode one DSE
|
||||
*
|
||||
* Inputs: BitStreamInfo struct pointing to start of DSE (14496-3, table 4.4.10)
|
||||
*
|
||||
* Outputs: updated element instance tag
|
||||
* filled in data stream buffer
|
||||
*
|
||||
* Return: 0 if successful, -1 if error
|
||||
**************************************************************************************/
|
||||
static int DecodeDataStreamElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi)
|
||||
{
|
||||
unsigned int byteAlign, dataCount;
|
||||
unsigned char *dataBuf;
|
||||
PSInfoBase *psi;
|
||||
|
||||
/* validate pointers */
|
||||
if (!aacDecInfo || !aacDecInfo->psInfoBase)
|
||||
return -1;
|
||||
psi = (PSInfoBase *)(aacDecInfo->psInfoBase);
|
||||
|
||||
aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS);
|
||||
byteAlign = GetBits(bsi, 1);
|
||||
dataCount = GetBits(bsi, 8);
|
||||
if (dataCount == 255)
|
||||
dataCount += GetBits(bsi, 8);
|
||||
|
||||
if (byteAlign)
|
||||
ByteAlignBitstream(bsi);
|
||||
|
||||
psi->dataCount = dataCount;
|
||||
dataBuf = psi->dataBuf;
|
||||
while (dataCount--)
|
||||
*dataBuf++ = GetBits(bsi, 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
* Function: DecodeProgramConfigElement
|
||||
*
|
||||
* Description: decode one PCE
|
||||
*
|
||||
* Inputs: BitStreamInfo struct pointing to start of PCE (14496-3, table 4.4.2)
|
||||
*
|
||||
* Outputs: filled-in ProgConfigElement struct
|
||||
* updated BitStreamInfo struct
|
||||
*
|
||||
* Return: 0 if successful, error code (< 0) if error
|
||||
*
|
||||
* Notes: #define KEEP_PCE_COMMENTS to save the comment field of the PCE
|
||||
* (otherwise we just skip it in the bitstream, to save memory)
|
||||
**************************************************************************************/
|
||||
int DecodeProgramConfigElement(ProgConfigElement *pce, BitStreamInfo *bsi)
|
||||
{
|
||||
int i;
|
||||
|
||||
pce->elemInstTag = GetBits(bsi, 4);
|
||||
pce->profile = GetBits(bsi, 2);
|
||||
pce->sampRateIdx = GetBits(bsi, 4);
|
||||
pce->numFCE = GetBits(bsi, 4);
|
||||
pce->numSCE = GetBits(bsi, 4);
|
||||
pce->numBCE = GetBits(bsi, 4);
|
||||
pce->numLCE = GetBits(bsi, 2);
|
||||
pce->numADE = GetBits(bsi, 3);
|
||||
pce->numCCE = GetBits(bsi, 4);
|
||||
|
||||
pce->monoMixdown = GetBits(bsi, 1) << 4; /* present flag */
|
||||
if (pce->monoMixdown)
|
||||
pce->monoMixdown |= GetBits(bsi, 4); /* element number */
|
||||
|
||||
pce->stereoMixdown = GetBits(bsi, 1) << 4; /* present flag */
|
||||
if (pce->stereoMixdown)
|
||||
pce->stereoMixdown |= GetBits(bsi, 4); /* element number */
|
||||
|
||||
pce->matrixMixdown = GetBits(bsi, 1) << 4; /* present flag */
|
||||
if (pce->matrixMixdown) {
|
||||
pce->matrixMixdown |= GetBits(bsi, 2) << 1; /* index */
|
||||
pce->matrixMixdown |= GetBits(bsi, 1); /* pseudo-surround enable */
|
||||
}
|
||||
|
||||
for (i = 0; i < pce->numFCE; i++) {
|
||||
pce->fce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */
|
||||
pce->fce[i] |= GetBits(bsi, 4); /* tag select */
|
||||
}
|
||||
|
||||
for (i = 0; i < pce->numSCE; i++) {
|
||||
pce->sce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */
|
||||
pce->sce[i] |= GetBits(bsi, 4); /* tag select */
|
||||
}
|
||||
|
||||
for (i = 0; i < pce->numBCE; i++) {
|
||||
pce->bce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */
|
||||
pce->bce[i] |= GetBits(bsi, 4); /* tag select */
|
||||
}
|
||||
|
||||
for (i = 0; i < pce->numLCE; i++)
|
||||
pce->lce[i] = GetBits(bsi, 4); /* tag select */
|
||||
|
||||
for (i = 0; i < pce->numADE; i++)
|
||||
pce->ade[i] = GetBits(bsi, 4); /* tag select */
|
||||
|
||||
for (i = 0; i < pce->numCCE; i++) {
|
||||
pce->cce[i] = GetBits(bsi, 1) << 4; /* independent/dependent flag */
|
||||
pce->cce[i] |= GetBits(bsi, 4); /* tag select */
|
||||
}
|
||||
|
||||
|
||||
ByteAlignBitstream(bsi);
|
||||
|
||||
#ifdef KEEP_PCE_COMMENTS
|
||||
pce->commentBytes = GetBits(bsi, 8);
|
||||
for (i = 0; i < pce->commentBytes; i++)
|
||||
pce->commentField[i] = GetBits(bsi, 8);
|
||||
#else
|
||||
/* eat comment bytes and throw away */
|
||||
i = GetBits(bsi, 8);
|
||||
while (i--)
|
||||
GetBits(bsi, 8);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
* Function: DecodeFillElement
|
||||
*
|
||||
* Description: decode one fill element
|
||||
*
|
||||
* Inputs: BitStreamInfo struct pointing to start of fill element
|
||||
* (14496-3, table 4.4.11)
|
||||
*
|
||||
* Outputs: updated element instance tag
|
||||
* unpacked extension payload
|
||||
*
|
||||
* Return: 0 if successful, -1 if error
|
||||
**************************************************************************************/
|
||||
static int DecodeFillElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi)
|
||||
{
|
||||
unsigned int fillCount;
|
||||
unsigned char *fillBuf;
|
||||
PSInfoBase *psi;
|
||||
|
||||
/* validate pointers */
|
||||
if (!aacDecInfo || !aacDecInfo->psInfoBase)
|
||||
return -1;
|
||||
psi = (PSInfoBase *)(aacDecInfo->psInfoBase);
|
||||
|
||||
fillCount = GetBits(bsi, 4);
|
||||
if (fillCount == 15)
|
||||
fillCount += (GetBits(bsi, 8) - 1);
|
||||
|
||||
psi->fillCount = fillCount;
|
||||
fillBuf = psi->fillBuf;
|
||||
while (fillCount--)
|
||||
*fillBuf++ = GetBits(bsi, 8);
|
||||
|
||||
aacDecInfo->currInstTag = -1; /* fill elements don't have instance tag */
|
||||
aacDecInfo->fillExtType = 0;
|
||||
|
||||
#ifdef AAC_ENABLE_SBR
|
||||
/* check for SBR
|
||||
* aacDecInfo->sbrEnabled is sticky (reset each raw_data_block), so for multichannel
|
||||
* need to verify that all SCE/CPE/ICCE have valid SBR fill element following, and
|
||||
* must upsample by 2 for LFE
|
||||
*/
|
||||
if (psi->fillCount > 0) {
|
||||
aacDecInfo->fillExtType = (int)((psi->fillBuf[0] >> 4) & 0x0f);
|
||||
if (aacDecInfo->fillExtType == EXT_SBR_DATA || aacDecInfo->fillExtType == EXT_SBR_DATA_CRC)
|
||||
aacDecInfo->sbrEnabled = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
aacDecInfo->fillBuf = psi->fillBuf;
|
||||
aacDecInfo->fillCount = psi->fillCount;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
* Function: DecodeNextElement
|
||||
*
|
||||
* Description: decode next syntactic element in AAC frame
|
||||
*
|
||||
* Inputs: valid AACDecInfo struct
|
||||
* double pointer to buffer containing next element
|
||||
* pointer to bit offset
|
||||
* pointer to number of valid bits remaining in buf
|
||||
*
|
||||
* Outputs: type of element decoded (aacDecInfo->currBlockID)
|
||||
* type of element decoded last time (aacDecInfo->prevBlockID)
|
||||
* updated aacDecInfo state, depending on which element was decoded
|
||||
* updated buffer pointer
|
||||
* updated bit offset
|
||||
* updated number of available bits
|
||||
*
|
||||
* Return: 0 if successful, error code (< 0) if error
|
||||
**************************************************************************************/
|
||||
int DecodeNextElement(AACDecInfo *aacDecInfo, unsigned char **buf, int *bitOffset, int *bitsAvail)
|
||||
{
|
||||
int err, bitsUsed;
|
||||
PSInfoBase *psi;
|
||||
BitStreamInfo bsi;
|
||||
|
||||
/* validate pointers */
|
||||
if (!aacDecInfo || !aacDecInfo->psInfoBase)
|
||||
return ERR_AAC_NULL_POINTER;
|
||||
psi = (PSInfoBase *)(aacDecInfo->psInfoBase);
|
||||
|
||||
/* init bitstream reader */
|
||||
SetBitstreamPointer(&bsi, (*bitsAvail + 7) >> 3, *buf);
|
||||
GetBits(&bsi, *bitOffset);
|
||||
|
||||
/* read element ID (save last ID for SBR purposes) */
|
||||
aacDecInfo->prevBlockID = aacDecInfo->currBlockID;
|
||||
aacDecInfo->currBlockID = GetBits(&bsi, NUM_SYN_ID_BITS);
|
||||
|
||||
/* set defaults (could be overwritten by DecodeXXXElement(), depending on currBlockID) */
|
||||
psi->commonWin = 0;
|
||||
|
||||
err = 0;
|
||||
switch (aacDecInfo->currBlockID) {
|
||||
case AAC_ID_SCE:
|
||||
err = DecodeSingleChannelElement(aacDecInfo, &bsi);
|
||||
break;
|
||||
case AAC_ID_CPE:
|
||||
err = DecodeChannelPairElement(aacDecInfo, &bsi);
|
||||
break;
|
||||
case AAC_ID_CCE:
|
||||
/* TODO - implement CCE decoding */
|
||||
break;
|
||||
case AAC_ID_LFE:
|
||||
err = DecodeLFEChannelElement(aacDecInfo, &bsi);
|
||||
break;
|
||||
case AAC_ID_DSE:
|
||||
err = DecodeDataStreamElement(aacDecInfo, &bsi);
|
||||
break;
|
||||
case AAC_ID_PCE:
|
||||
err = DecodeProgramConfigElement(psi->pce + 0, &bsi);
|
||||
break;
|
||||
case AAC_ID_FIL:
|
||||
err = DecodeFillElement(aacDecInfo, &bsi);
|
||||
break;
|
||||
case AAC_ID_END:
|
||||
break;
|
||||
}
|
||||
if (err)
|
||||
return ERR_AAC_SYNTAX_ELEMENT;
|
||||
|
||||
/* update bitstream reader */
|
||||
bitsUsed = CalcBitsUsed(&bsi, *buf, *bitOffset);
|
||||
*buf += (bitsUsed + *bitOffset) >> 3;
|
||||
*bitOffset = (bitsUsed + *bitOffset) & 0x07;
|
||||
*bitsAvail -= bitsUsed;
|
||||
|
||||
if (*bitsAvail < 0)
|
||||
return ERR_AAC_INDATA_UNDERFLOW;
|
||||
|
||||
return ERR_AAC_NONE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user