1
0
mirror of https://github.com/mstorsjo/fdk-aac.git synced 2025-02-18 04:00:36 +01:00

Merge "Merge Android 12"

This commit is contained in:
Xin Li 2021-10-07 23:50:23 +00:00 committed by Gerrit Code Review
commit 0bfa3fc1cd
48 changed files with 1162 additions and 823 deletions

Binary file not shown.

Binary file not shown.

View File

@ -118,7 +118,8 @@ void Codec::decodeFrames(UCHAR *data, UINT size) {
INT_PCM outputBuf[kMaxOutBufferSize]; INT_PCM outputBuf[kMaxOutBufferSize];
do { do {
mErrorCode = mErrorCode =
aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, sizeof(outputBuf), 0); aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf,
kMaxOutBufferSize /*size in number of INT_PCM, not bytes*/, 0);
} while (mErrorCode == AAC_DEC_OK); } while (mErrorCode == AAC_DEC_OK);
UINT offset = inputSize - valid; UINT offset = inputSize - valid;
data += offset; data += offset;

View File

@ -1032,7 +1032,7 @@ LINKSPEC_H AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self,
* \param self AAC decoder handle. * \param self AAC decoder handle.
* \param pTimeData Pointer to external output buffer where the decoded PCM * \param pTimeData Pointer to external output buffer where the decoded PCM
* samples will be stored into. * samples will be stored into.
* \param timeDataSize Size of external output buffer. * \param timeDataSize Size of external output buffer in PCM samples.
* \param flags Bit field with flags for the decoder: \n * \param flags Bit field with flags for the decoder: \n
* (flags & AACDEC_CONCEAL) == 1: Do concealment. \n * (flags & AACDEC_CONCEAL) == 1: Do concealment. \n
* (flags & AACDEC_FLUSH) == 2: Discard input data. Flush * (flags & AACDEC_FLUSH) == 2: Discard input data. Flush

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -148,7 +148,7 @@ C_ALLOC_MEM(CplxPredictionData, CCplxPredictionData, 1)
/*! The buffer holds time samples for the crossfade in case of an USAC DASH IPF /*! The buffer holds time samples for the crossfade in case of an USAC DASH IPF
config change Dimension: (8) config change Dimension: (8)
*/ */
C_ALLOC_MEM2(TimeDataFlush, INT_PCM, TIME_DATA_FLUSH_SIZE, (8)) C_ALLOC_MEM2(TimeDataFlush, PCM_DEC, TIME_DATA_FLUSH_SIZE, (8))
/* @} */ /* @} */

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -132,7 +132,7 @@ H_ALLOC_MEM(CplxPredictionData, CCplxPredictionData)
H_ALLOC_MEM(SpectralCoeffs, FIXP_DBL) H_ALLOC_MEM(SpectralCoeffs, FIXP_DBL)
H_ALLOC_MEM(SpecScale, SHORT) H_ALLOC_MEM(SpecScale, SHORT)
H_ALLOC_MEM(TimeDataFlush, INT_PCM) H_ALLOC_MEM(TimeDataFlush, PCM_DEC)
H_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1) H_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1)
H_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL) H_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL)

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -149,6 +149,19 @@ static INT convert_drcParam(FIXP_DBL param_dbl) {
return (INT)param_long; return (INT)param_long;
} }
/*!
\brief Disable DRC
\self Handle of DRC info
\return none
*/
void aacDecoder_drcDisable(HANDLE_AAC_DRC self) {
self->enable = 0;
self->applyExtGain = 0;
self->progRefLevelPresent = 0;
}
/*! /*!
\brief Reset DRC information \brief Reset DRC information

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -140,6 +140,8 @@ typedef enum {
/** /**
* \brief DRC module interface functions * \brief DRC module interface functions
*/ */
void aacDecoder_drcDisable(HANDLE_AAC_DRC self);
void aacDecoder_drcReset(HANDLE_AAC_DRC self); void aacDecoder_drcReset(HANDLE_AAC_DRC self);
void aacDecoder_drcInit(HANDLE_AAC_DRC self); void aacDecoder_drcInit(HANDLE_AAC_DRC self);

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -173,7 +173,9 @@ void DecodeNonPCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
pHcr->segmentInfo.readDirection = FROM_RIGHT_TO_LEFT; pHcr->segmentInfo.readDirection = FROM_RIGHT_TO_LEFT;
/* Process sets subsequently */ /* Process sets subsequently */
numSet = fMin(numSet, (UCHAR)MAX_HCR_SETS);
for (currentSet = 1; currentSet < numSet; currentSet++) { for (currentSet = 1; currentSet < numSet; currentSet++) {
/* step 1 */ /* step 1 */
numCodeword -= numCodeword -=
*pNumSegment; /* number of remaining non PCWs [for all sets] */ *pNumSegment; /* number of remaining non PCWs [for all sets] */

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -494,6 +494,75 @@ static AAC_DECODER_ERROR CDataStreamElement_Read(HANDLE_AACDECODER self,
return error; return error;
} }
static INT findElementInstanceTag(
INT elementTag, MP4_ELEMENT_ID elementId,
CAacDecoderChannelInfo **pAacDecoderChannelInfo, INT nChannels,
MP4_ELEMENT_ID *pElementIdTab, INT nElements) {
int el, chCnt = 0;
for (el = 0; el < nElements; el++) {
switch (pElementIdTab[el]) {
case ID_CPE:
case ID_SCE:
case ID_LFE:
if ((elementTag == pAacDecoderChannelInfo[chCnt]->ElementInstanceTag) &&
(elementId == pElementIdTab[el])) {
return 1; /* element instance tag found */
}
chCnt += (pElementIdTab[el] == ID_CPE) ? 2 : 1;
break;
default:
break;
}
if (chCnt >= nChannels) break;
if (pElementIdTab[el] == ID_END) break;
}
return 0; /* element instance tag not found */
}
static INT validateElementInstanceTags(
CProgramConfig *pce, CAacDecoderChannelInfo **pAacDecoderChannelInfo,
INT nChannels, MP4_ELEMENT_ID *pElementIdTab, INT nElements) {
if (nChannels >= pce->NumChannels) {
for (int el = 0; el < pce->NumFrontChannelElements; el++) {
if (!findElementInstanceTag(pce->FrontElementTagSelect[el],
pce->FrontElementIsCpe[el] ? ID_CPE : ID_SCE,
pAacDecoderChannelInfo, nChannels,
pElementIdTab, nElements)) {
return 0; /* element instance tag not in raw_data_block() */
}
}
for (int el = 0; el < pce->NumSideChannelElements; el++) {
if (!findElementInstanceTag(pce->SideElementTagSelect[el],
pce->SideElementIsCpe[el] ? ID_CPE : ID_SCE,
pAacDecoderChannelInfo, nChannels,
pElementIdTab, nElements)) {
return 0; /* element instance tag not in raw_data_block() */
}
}
for (int el = 0; el < pce->NumBackChannelElements; el++) {
if (!findElementInstanceTag(pce->BackElementTagSelect[el],
pce->BackElementIsCpe[el] ? ID_CPE : ID_SCE,
pAacDecoderChannelInfo, nChannels,
pElementIdTab, nElements)) {
return 0; /* element instance tag not in raw_data_block() */
}
}
for (int el = 0; el < pce->NumLfeChannelElements; el++) {
if (!findElementInstanceTag(pce->LfeElementTagSelect[el], ID_LFE,
pAacDecoderChannelInfo, nChannels,
pElementIdTab, nElements)) {
return 0; /* element instance tag not in raw_data_block() */
}
}
} else {
return 0; /* too less decoded audio channels */
}
return 1; /* all element instance tags found in raw_data_block() */
}
/*! /*!
\brief Read Program Config Element \brief Read Program Config Element
@ -568,7 +637,7 @@ static int CProgramConfigElement_Read(HANDLE_FDK_BITSTREAM bs,
\return Error code \return Error code
*/ */
LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade( LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade(
const INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels, const PCM_DEC *pTimeData, PCM_DEC **pTimeDataFlush, const INT numChannels,
const INT frameSize, const INT interleaved) { const INT frameSize, const INT interleaved) {
int i, ch, s1, s2; int i, ch, s1, s2;
AAC_DECODER_ERROR ErrorStatus; AAC_DECODER_ERROR ErrorStatus;
@ -584,7 +653,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade(
} }
for (ch = 0; ch < numChannels; ch++) { for (ch = 0; ch < numChannels; ch++) {
const INT_PCM *pIn = &pTimeData[ch * s1]; const PCM_DEC *pIn = &pTimeData[ch * s1];
for (i = 0; i < TIME_DATA_FLUSH_SIZE; i++) { for (i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
pTimeDataFlush[ch][i] = *pIn; pTimeDataFlush[ch][i] = *pIn;
pIn += s2; pIn += s2;
@ -606,7 +675,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade(
\return Error code \return Error code
*/ */
LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_ApplyCrossFade( LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_ApplyCrossFade(
INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels, PCM_DEC *pTimeData, PCM_DEC **pTimeDataFlush, const INT numChannels,
const INT frameSize, const INT interleaved) { const INT frameSize, const INT interleaved) {
int i, ch, s1, s2; int i, ch, s1, s2;
AAC_DECODER_ERROR ErrorStatus; AAC_DECODER_ERROR ErrorStatus;
@ -622,15 +691,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_ApplyCrossFade(
} }
for (ch = 0; ch < numChannels; ch++) { for (ch = 0; ch < numChannels; ch++) {
INT_PCM *pIn = &pTimeData[ch * s1]; PCM_DEC *pIn = &pTimeData[ch * s1];
for (i = 0; i < TIME_DATA_FLUSH_SIZE; i++) { for (i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
FIXP_SGL alpha = (FIXP_SGL)i FIXP_SGL alpha = (FIXP_SGL)i
<< (FRACT_BITS - 1 - TIME_DATA_FLUSH_SIZE_SF); << (FRACT_BITS - 1 - TIME_DATA_FLUSH_SIZE_SF);
FIXP_DBL time = FX_PCM2FX_DBL(*pIn); FIXP_DBL time = PCM_DEC2FIXP_DBL(*pIn);
FIXP_DBL timeFlush = FX_PCM2FX_DBL(pTimeDataFlush[ch][i]); FIXP_DBL timeFlush = PCM_DEC2FIXP_DBL(pTimeDataFlush[ch][i]);
*pIn = (INT_PCM)(FIXP_PCM)FX_DBL2FX_PCM( *pIn = FIXP_DBL2PCM_DEC(timeFlush - fMult(timeFlush, alpha) +
timeFlush - fMult(timeFlush, alpha) + fMult(time, alpha)); fMult(time, alpha));
pIn += s2; pIn += s2;
} }
} }
@ -753,7 +822,12 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PreRollExtensionPayloadParse(
/* We are interested in preroll AUs if an explicit or an implicit config /* We are interested in preroll AUs if an explicit or an implicit config
* change is signalized in other words if the build up status is set. */ * change is signalized in other words if the build up status is set. */
if (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON) { if (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON) {
self->applyCrossfade |= FDKreadBit(hBs); UCHAR applyCrossfade = FDKreadBit(hBs);
if (applyCrossfade) {
self->applyCrossfade |= AACDEC_CROSSFADE_BITMASK_PREROLL;
} else {
self->applyCrossfade &= ~AACDEC_CROSSFADE_BITMASK_PREROLL;
}
FDKreadBit(hBs); /* reserved */ FDKreadBit(hBs); /* reserved */
/* Read num preroll AU's */ /* Read num preroll AU's */
*numPrerollAU = escapedValue(hBs, 2, 4, 0); *numPrerollAU = escapedValue(hBs, 2, 4, 0);
@ -1396,6 +1470,27 @@ static void CAacDecoder_DeInit(HANDLE_AACDECODER self,
self->samplingRateInfo[subStreamIndex].samplingRate = 0; self->samplingRateInfo[subStreamIndex].samplingRate = 0;
} }
/*!
* \brief CAacDecoder_AcceptFlags Accept flags and element flags
*
* \param self [o] handle to AACDECODER structure
* \param asc [i] handle to ASC structure
* \param flags [i] flags
* \param elFlags [i] pointer to element flags
* \param streamIndex [i] stream index
* \param elementOffset [i] element offset
*
* \return void
*/
static void CAacDecoder_AcceptFlags(HANDLE_AACDECODER self,
const CSAudioSpecificConfig *asc,
UINT flags, UINT *elFlags, int streamIndex,
int elementOffset) {
FDKmemcpy(self->elFlags, elFlags, sizeof(self->elFlags));
self->flags[streamIndex] = flags;
}
/*! /*!
* \brief CAacDecoder_CtrlCFGChange Set config change parameters. * \brief CAacDecoder_CtrlCFGChange Set config change parameters.
* *
@ -1493,6 +1588,15 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
const int streamIndex = 0; const int streamIndex = 0;
INT flushChannels = 0; INT flushChannels = 0;
UINT flags;
/* elFlags[(3*MAX_CHANNELS + (MAX_CHANNELS)/2 + 4 * (MAX_TRACKS) + 1]
where MAX_CHANNELS is (8*2) and MAX_TRACKS is 1 */
UINT elFlags[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)];
UCHAR sbrEnabled = self->sbrEnabled;
UCHAR sbrEnabledPrev = self->sbrEnabledPrev;
UCHAR mpsEnableCurr = self->mpsEnableCurr;
if (!self) return AAC_DEC_INVALID_HANDLE; if (!self) return AAC_DEC_INVALID_HANDLE;
UCHAR downscaleFactor = self->downscaleFactor; UCHAR downscaleFactor = self->downscaleFactor;
@ -1649,8 +1753,8 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
} }
/* Set syntax flags */ /* Set syntax flags */
self->flags[streamIndex] = 0; flags = 0;
{ FDKmemclear(self->elFlags, sizeof(self->elFlags)); } { FDKmemclear(elFlags, sizeof(elFlags)); }
if ((asc->m_channelConfiguration > 0) || IS_USAC(asc->m_aot)) { if ((asc->m_channelConfiguration > 0) || IS_USAC(asc->m_aot)) {
if (IS_USAC(asc->m_aot)) { if (IS_USAC(asc->m_aot)) {
@ -1676,7 +1780,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
asc->m_sc.m_usacConfig.m_usacNumElements; asc->m_sc.m_usacConfig.m_usacNumElements;
} }
self->mpsEnableCurr = 0; mpsEnableCurr = 0;
for (int _el = 0; for (int _el = 0;
_el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements; _el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements;
_el++) { _el++) {
@ -1696,35 +1800,34 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
self->usacStereoConfigIndex[el] = self->usacStereoConfigIndex[el] =
asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex; asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex;
if (self->elements[el] == ID_USAC_CPE) { if (self->elements[el] == ID_USAC_CPE) {
self->mpsEnableCurr |= self->usacStereoConfigIndex[el] ? 1 : 0; mpsEnableCurr |= self->usacStereoConfigIndex[el] ? 1 : 0;
} }
} }
self->elFlags[el] |= elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].m_noiseFilling)
(asc->m_sc.m_usacConfig.element[_el].m_noiseFilling)
? AC_EL_USAC_NOISE ? AC_EL_USAC_NOISE
: 0; : 0;
self->elFlags[el] |= elFlags[el] |=
(asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex > 0) (asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex > 0)
? AC_EL_USAC_MPS212 ? AC_EL_USAC_MPS212
: 0; : 0;
self->elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].m_interTes) elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].m_interTes)
? AC_EL_USAC_ITES ? AC_EL_USAC_ITES
: 0; : 0;
self->elFlags[el] |= elFlags[el] |=
(asc->m_sc.m_usacConfig.element[_el].m_pvc) ? AC_EL_USAC_PVC : 0; (asc->m_sc.m_usacConfig.element[_el].m_pvc) ? AC_EL_USAC_PVC : 0;
self->elFlags[el] |= elFlags[el] |=
(asc->m_sc.m_usacConfig.element[_el].usacElementType == ID_USAC_LFE) (asc->m_sc.m_usacConfig.element[_el].usacElementType == ID_USAC_LFE)
? AC_EL_USAC_LFE ? AC_EL_USAC_LFE
: 0; : 0;
self->elFlags[el] |= elFlags[el] |=
(asc->m_sc.m_usacConfig.element[_el].usacElementType == ID_USAC_LFE) (asc->m_sc.m_usacConfig.element[_el].usacElementType == ID_USAC_LFE)
? AC_EL_LFE ? AC_EL_LFE
: 0; : 0;
if ((asc->m_sc.m_usacConfig.element[_el].usacElementType == if ((asc->m_sc.m_usacConfig.element[_el].usacElementType ==
ID_USAC_CPE) && ID_USAC_CPE) &&
((self->usacStereoConfigIndex[el] == 0))) { ((self->usacStereoConfigIndex[el] == 0))) {
self->elFlags[el] |= AC_EL_USAC_CP_POSSIBLE; elFlags[el] |= AC_EL_USAC_CP_POSSIBLE;
} }
} }
@ -1791,9 +1894,17 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
downscaleFactorInBS = downscaleFactorInBS =
asc->m_samplingFrequency / asc->m_samplingFrequency /
asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency; asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency;
if (downscaleFactorInBS == 1 || downscaleFactorInBS == 2 || if ((downscaleFactorInBS == 1 || downscaleFactorInBS == 2 ||
downscaleFactorInBS == 3 || downscaleFactorInBS == 4) { (downscaleFactorInBS == 3 &&
asc->m_sc.m_eldSpecificConfig.m_frameLengthFlag) ||
downscaleFactorInBS == 4) &&
((asc->m_samplingFrequency %
asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency) ==
0)) {
downscaleFactor = downscaleFactorInBS; downscaleFactor = downscaleFactorInBS;
} else {
downscaleFactorInBS = 1;
downscaleFactor = 1;
} }
} }
} else { } else {
@ -1825,7 +1936,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
self->useLdQmfTimeAlign = self->useLdQmfTimeAlign =
asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign; asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign;
} }
if (self->sbrEnabled != asc->m_sbrPresentFlag) { if (sbrEnabled != asc->m_sbrPresentFlag) {
ascChanged = 1; ascChanged = 1;
} }
} }
@ -1838,16 +1949,16 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
if (configMode & AC_CM_ALLOC_MEM) { if (configMode & AC_CM_ALLOC_MEM) {
self->streamInfo.extSamplingRate = asc->m_extensionSamplingFrequency; self->streamInfo.extSamplingRate = asc->m_extensionSamplingFrequency;
} }
self->flags[streamIndex] |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0; flags |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0;
self->flags[streamIndex] |= (asc->m_psPresentFlag) ? AC_PS_PRESENT : 0; flags |= (asc->m_psPresentFlag) ? AC_PS_PRESENT : 0;
if (asc->m_sbrPresentFlag) { if (asc->m_sbrPresentFlag) {
self->sbrEnabled = 1; sbrEnabled = 1;
self->sbrEnabledPrev = 1; sbrEnabledPrev = 1;
} else { } else {
self->sbrEnabled = 0; sbrEnabled = 0;
self->sbrEnabledPrev = 0; sbrEnabledPrev = 0;
} }
if (self->sbrEnabled && asc->m_extensionSamplingFrequency) { if (sbrEnabled && asc->m_extensionSamplingFrequency) {
if (downscaleFactor != 1 && (downscaleFactor)&1) { if (downscaleFactor != 1 && (downscaleFactor)&1) {
return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* SBR needs an even downscale return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* SBR needs an even downscale
factor */ factor */
@ -1865,51 +1976,47 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
} }
/* --------- vcb11 ------------ */ /* --------- vcb11 ------------ */
self->flags[streamIndex] |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0; flags |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0;
/* ---------- rvlc ------------ */ /* ---------- rvlc ------------ */
self->flags[streamIndex] |= (asc->m_rvlcFlag) ? AC_ER_RVLC : 0; flags |= (asc->m_rvlcFlag) ? AC_ER_RVLC : 0;
/* ----------- hcr ------------ */ /* ----------- hcr ------------ */
self->flags[streamIndex] |= (asc->m_hcrFlag) ? AC_ER_HCR : 0; flags |= (asc->m_hcrFlag) ? AC_ER_HCR : 0;
if (asc->m_aot == AOT_ER_AAC_ELD) { if (asc->m_aot == AOT_ER_AAC_ELD) {
self->mpsEnableCurr = 0; mpsEnableCurr = 0;
self->flags[streamIndex] |= AC_ELD; flags |= AC_ELD;
self->flags[streamIndex] |= flags |= (asc->m_sbrPresentFlag)
(asc->m_sbrPresentFlag)
? AC_SBR_PRESENT ? AC_SBR_PRESENT
: 0; /* Need to set the SBR flag for backward-compatibility : 0; /* Need to set the SBR flag for backward-compatibility
reasons. Even if SBR is not supported. */ reasons. Even if SBR is not supported. */
self->flags[streamIndex] |= flags |= (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0;
(asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0; flags |= (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign)
self->flags[streamIndex] |= ? AC_MPS_PRESENT
(asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) ? AC_MPS_PRESENT
: 0; : 0;
if (self->mpsApplicable) { if (self->mpsApplicable) {
self->mpsEnableCurr = asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign; mpsEnableCurr = asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign;
} }
} }
self->flags[streamIndex] |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0; flags |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0;
self->flags[streamIndex] |= (asc->m_epConfig >= 0) ? AC_ER : 0; flags |= (asc->m_epConfig >= 0) ? AC_ER : 0;
if (asc->m_aot == AOT_USAC) { if (asc->m_aot == AOT_USAC) {
self->flags[streamIndex] |= AC_USAC; flags |= AC_USAC;
self->flags[streamIndex] |= flags |= (asc->m_sc.m_usacConfig.element[0].m_stereoConfigIndex > 0)
(asc->m_sc.m_usacConfig.element[0].m_stereoConfigIndex > 0)
? AC_MPS_PRESENT ? AC_MPS_PRESENT
: 0; : 0;
} }
if (asc->m_aot == AOT_DRM_AAC) { if (asc->m_aot == AOT_DRM_AAC) {
self->flags[streamIndex] |= AC_DRM | AC_SBRCRC | AC_SCALABLE; flags |= AC_DRM | AC_SBRCRC | AC_SCALABLE;
} }
if (asc->m_aot == AOT_DRM_SURROUND) { if (asc->m_aot == AOT_DRM_SURROUND) {
self->flags[streamIndex] |= flags |= AC_DRM | AC_SBRCRC | AC_SCALABLE | AC_MPS_PRESENT;
AC_DRM | AC_SBRCRC | AC_SCALABLE | AC_MPS_PRESENT;
FDK_ASSERT(!asc->m_psPresentFlag); FDK_ASSERT(!asc->m_psPresentFlag);
} }
if ((asc->m_aot == AOT_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_SCAL)) { if ((asc->m_aot == AOT_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_SCAL)) {
self->flags[streamIndex] |= AC_SCALABLE; flags |= AC_SCALABLE;
} }
if ((asc->m_epConfig >= 0) && (asc->m_channelConfiguration <= 0)) { if ((asc->m_epConfig >= 0) && (asc->m_channelConfiguration <= 0)) {
@ -1960,13 +2067,17 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
if (ascChanged != 0) { if (ascChanged != 0) {
*configChanged = 1; *configChanged = 1;
} }
CAacDecoder_AcceptFlags(self, asc, flags, elFlags, streamIndex,
elementOffset);
return err; return err;
} }
/* set AC_USAC_SCFGI3 globally if any usac element uses */ /* set AC_USAC_SCFGI3 globally if any usac element uses */
switch (asc->m_aot) { switch (asc->m_aot) {
case AOT_USAC: case AOT_USAC:
if (self->sbrEnabled) { if (sbrEnabled) {
for (int _el = 0; for (int _el = 0;
_el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements; _el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements;
_el++) { _el++) {
@ -1988,7 +2099,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
} }
if (usacStereoConfigIndex == 3) { if (usacStereoConfigIndex == 3) {
self->flags[streamIndex] |= AC_USAC_SCFGI3; flags |= AC_USAC_SCFGI3;
} }
} }
break; break;
@ -2003,7 +2114,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
*/ */
switch (asc->m_aot) { switch (asc->m_aot) {
case AOT_USAC: case AOT_USAC:
if (self->sbrEnabled) { if (sbrEnabled) {
const UCHAR map_sbrRatio_2_nAnaBands[] = {16, 24, 32}; const UCHAR map_sbrRatio_2_nAnaBands[] = {16, 24, 32};
FDK_ASSERT(asc->m_sc.m_usacConfig.m_sbrRatioIndex > 0); FDK_ASSERT(asc->m_sc.m_usacConfig.m_sbrRatioIndex > 0);
@ -2031,10 +2142,10 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
} }
break; break;
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
if (self->mpsEnableCurr && if (mpsEnableCurr &&
asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) { asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) {
SAC_INPUT_CONFIG sac_interface = SAC_INPUT_CONFIG sac_interface = (sbrEnabled && self->hSbrDecoder)
(self->sbrEnabled && self->hSbrDecoder) ? SAC_INTERFACE_QMF ? SAC_INTERFACE_QMF
: SAC_INTERFACE_TIME; : SAC_INTERFACE_TIME;
mpegSurroundDecoder_ConfigureQmfDomain( mpegSurroundDecoder_ConfigureQmfDomain(
(CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface, (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface,
@ -2069,14 +2180,14 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
ch = aacChannelsOffset; ch = aacChannelsOffset;
int _numElements; int _numElements;
_numElements = (((8)) + (8)); _numElements = (((8)) + (8));
if (self->flags[streamIndex] & (AC_RSV603DA | AC_USAC)) { if (flags & (AC_RSV603DA | AC_USAC)) {
_numElements = (int)asc->m_sc.m_usacConfig.m_usacNumElements; _numElements = (int)asc->m_sc.m_usacConfig.m_usacNumElements;
} }
for (int _el = 0; _el < _numElements; _el++) { for (int _el = 0; _el < _numElements; _el++) {
int el_channels = 0; int el_channels = 0;
int el = elementOffset + _el; int el = elementOffset + _el;
if (self->flags[streamIndex] & if (flags &
(AC_ER | AC_LD | AC_ELD | AC_RSV603DA | AC_USAC | AC_RSVD50)) { (AC_ER | AC_LD | AC_ELD | AC_RSV603DA | AC_USAC | AC_RSVD50)) {
if (ch >= ascChannels) { if (ch >= ascChannels) {
break; break;
@ -2176,15 +2287,14 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
if (self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer == NULL) { if (self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer == NULL) {
goto bail; goto bail;
} }
if (self->flags[streamIndex] & if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA /*|AC_BSAC*/)) {
(AC_USAC | AC_RSVD50 | AC_RSV603DA /*|AC_BSAC*/)) {
self->pAacDecoderStaticChannelInfo[ch]->hArCo = CArco_Create(); self->pAacDecoderStaticChannelInfo[ch]->hArCo = CArco_Create();
if (self->pAacDecoderStaticChannelInfo[ch]->hArCo == NULL) { if (self->pAacDecoderStaticChannelInfo[ch]->hArCo == NULL) {
goto bail; goto bail;
} }
} }
if (!(self->flags[streamIndex] & (AC_USAC | AC_RSV603DA))) { if (!(flags & (AC_USAC | AC_RSV603DA))) {
CPns_UpdateNoiseState( CPns_UpdateNoiseState(
&self->pAacDecoderChannelInfo[ch]->data.aac.PnsData, &self->pAacDecoderChannelInfo[ch]->data.aac.PnsData,
&self->pAacDecoderStaticChannelInfo[ch]->pnsCurrentSeed, &self->pAacDecoderStaticChannelInfo[ch]->pnsCurrentSeed,
@ -2195,7 +2305,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
chIdx++; chIdx++;
} }
if (self->flags[streamIndex] & AC_USAC) { if (flags & AC_USAC) {
for (int _ch = 0; _ch < flushChannels; _ch++) { for (int _ch = 0; _ch < flushChannels; _ch++) {
ch = aacChannelsOffset + _ch; ch = aacChannelsOffset + _ch;
if (self->pTimeDataFlush[ch] == NULL) { if (self->pTimeDataFlush[ch] == NULL) {
@ -2207,7 +2317,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
} }
} }
if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA)) { if (flags & (AC_USAC | AC_RSV603DA)) {
int complexStereoPredPossible = 0; int complexStereoPredPossible = 0;
ch = aacChannelsOffset; ch = aacChannelsOffset;
chIdx = aacChannelsOffsetIdx; chIdx = aacChannelsOffsetIdx;
@ -2223,7 +2333,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
elCh = 1; elCh = 1;
} }
if (self->elFlags[el2] & AC_EL_USAC_CP_POSSIBLE) { if (elFlags[el2] & AC_EL_USAC_CP_POSSIBLE) {
complexStereoPredPossible = 1; complexStereoPredPossible = 1;
if (self->cpeStaticData[el2] == NULL) { if (self->cpeStaticData[el2] == NULL) {
self->cpeStaticData[el2] = GetCpePersistentData(); self->cpeStaticData[el2] = GetCpePersistentData();
@ -2360,9 +2470,6 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
} }
} }
/* Update externally visible copy of flags */
self->streamInfo.flags = self->flags[0];
if (*configChanged) { if (*configChanged) {
int drcDecSampleRate, drcDecFrameSize; int drcDecSampleRate, drcDecFrameSize;
@ -2383,8 +2490,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
if (*configChanged) { if (*configChanged) {
if (asc->m_aot == AOT_USAC) { if (asc->m_aot == AOT_USAC) {
self->hDrcInfo->enable = 0; aacDecoder_drcDisable(self->hDrcInfo);
self->hDrcInfo->progRefLevelPresent = 0;
} }
} }
@ -2393,6 +2499,15 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
pcmLimiter_SetThreshold(self->hLimiter, FL2FXCONST_DBL(0.89125094f)); pcmLimiter_SetThreshold(self->hLimiter, FL2FXCONST_DBL(0.89125094f));
} }
CAacDecoder_AcceptFlags(self, asc, flags, elFlags, streamIndex,
elementOffset);
self->sbrEnabled = sbrEnabled;
self->sbrEnabledPrev = sbrEnabledPrev;
self->mpsEnableCurr = mpsEnableCurr;
/* Update externally visible copy of flags */
self->streamInfo.flags = self->flags[0];
return err; return err;
bail: bail:
@ -2927,6 +3042,24 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
} /* while ( (type != ID_END) ... ) */ } /* while ( (type != ID_END) ... ) */
if (!(self->flags[streamIndex] &
(AC_USAC | AC_RSVD50 | AC_RSV603DA | AC_BSAC | AC_LD | AC_ELD | AC_ER |
AC_SCALABLE)) &&
(self->streamInfo.channelConfig == 0) && pce->isValid &&
(ErrorStatus == AAC_DEC_OK) && self->frameOK &&
!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) {
/* Check whether all PCE listed element instance tags are present in
* raw_data_block() */
if (!validateElementInstanceTags(
&self->pce, self->pAacDecoderChannelInfo, aacChannels,
channel_elements,
fMin(channel_element_count, (int)(sizeof(channel_elements) /
sizeof(*channel_elements))))) {
ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
self->frameOK = 0;
}
}
if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) { if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) {
/* float decoder checks if bitsLeft is in range 0-7; only prerollAUs are /* float decoder checks if bitsLeft is in range 0-7; only prerollAUs are
* byteAligned with respect to the first bit */ * byteAligned with respect to the first bit */
@ -3194,11 +3327,12 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
* data in the bitstream. */ * data in the bitstream. */
self->flags[streamIndex] |= AC_DRC_PRESENT; self->flags[streamIndex] |= AC_DRC_PRESENT;
} else { } else {
self->hDrcInfo->enable = 0;
self->hDrcInfo->progRefLevelPresent = 0;
ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT; ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT;
} }
} }
if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA)) {
aacDecoder_drcDisable(self->hDrcInfo);
}
/* Create a reverse mapping table */ /* Create a reverse mapping table */
UCHAR Reverse_chMapping[((8) * 2)]; UCHAR Reverse_chMapping[((8) * 2)];
@ -3441,11 +3575,12 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
* data in the bitstream. */ * data in the bitstream. */
self->flags[streamIndex] |= AC_DRC_PRESENT; self->flags[streamIndex] |= AC_DRC_PRESENT;
} else { } else {
self->hDrcInfo->enable = 0;
self->hDrcInfo->progRefLevelPresent = 0;
ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT; ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT;
} }
} }
if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA)) {
aacDecoder_drcDisable(self->hDrcInfo);
}
} }
/* Add additional concealment delay */ /* Add additional concealment delay */

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -172,6 +172,12 @@ enum {
AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND = 5 AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND = 5
}; };
#define AACDEC_CROSSFADE_BITMASK_OFF \
((UCHAR)0) /*!< No cross-fade between frames shall be applied at next \
config change. */
#define AACDEC_CROSSFADE_BITMASK_PREROLL \
((UCHAR)1 << 1) /*!< applyCrossfade is signaled in AudioPreRoll */
typedef struct { typedef struct {
/* Usac Extension Elements */ /* Usac Extension Elements */
USAC_EXT_ELEMENT_TYPE usacExtElementType[(3)]; USAC_EXT_ELEMENT_TYPE usacExtElementType[(3)];
@ -325,7 +331,7 @@ This structure is allocated once for each CPE. */
UINT loudnessInfoSetPosition[3]; UINT loudnessInfoSetPosition[3];
SCHAR defaultTargetLoudness; SCHAR defaultTargetLoudness;
INT_PCM PCM_DEC
*pTimeDataFlush[((8) * 2)]; /*!< Pointer to the flushed time data which *pTimeDataFlush[((8) * 2)]; /*!< Pointer to the flushed time data which
will be used for the crossfade in case of will be used for the crossfade in case of
an USAC DASH IPF config change */ an USAC DASH IPF config change */
@ -341,8 +347,8 @@ This structure is allocated once for each CPE. */
start position in the start position in the
bitstream */ bitstream */
INT accessUnit; /*!< Number of the actual processed preroll accessUnit */ INT accessUnit; /*!< Number of the actual processed preroll accessUnit */
UCHAR applyCrossfade; /*!< if set crossfade for seamless stream switching is UCHAR applyCrossfade; /*!< If any bit is set, cross-fade for seamless stream
applied */ switching is applied */
FDK_SignalDelay usacResidualDelay; /*!< Delay residual signal to compensate FDK_SignalDelay usacResidualDelay; /*!< Delay residual signal to compensate
for eSBR delay of DMX signal in case of for eSBR delay of DMX signal in case of
@ -439,12 +445,12 @@ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_FreeMem(HANDLE_AACDECODER self,
/* Prepare crossfade for USAC DASH IPF config change */ /* Prepare crossfade for USAC DASH IPF config change */
LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade( LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade(
const INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels, const PCM_DEC *pTimeData, PCM_DEC **pTimeDataFlush, const INT numChannels,
const INT frameSize, const INT interleaved); const INT frameSize, const INT interleaved);
/* Apply crossfade for USAC DASH IPF config change */ /* Apply crossfade for USAC DASH IPF config change */
LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_ApplyCrossFade( LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_ApplyCrossFade(
INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels, PCM_DEC *pTimeData, PCM_DEC **pTimeDataFlush, const INT numChannels,
const INT frameSize, const INT interleaved); const INT frameSize, const INT interleaved);
/* Set flush and build up mode */ /* Set flush and build up mode */

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -385,21 +385,19 @@ static INT aacDecoder_SbrCallback(
return errTp; return errTp;
} }
static INT aacDecoder_SscCallback(void *handle, HANDLE_FDK_BITSTREAM hBs, static INT aacDecoder_SscCallback(
const AUDIO_OBJECT_TYPE coreCodec, void *handle, HANDLE_FDK_BITSTREAM hBs, const AUDIO_OBJECT_TYPE coreCodec,
const INT samplingRate, const INT frameSize, const INT samplingRate, const INT frameSize, const INT numChannels,
const INT stereoConfigIndex, const INT stereoConfigIndex, const INT coreSbrFrameLengthIndex,
const INT coreSbrFrameLengthIndex, const INT configBytes, const UCHAR configMode, UCHAR *configChanged) {
const INT configBytes, const UCHAR configMode,
UCHAR *configChanged) {
SACDEC_ERROR err; SACDEC_ERROR err;
TRANSPORTDEC_ERROR errTp; TRANSPORTDEC_ERROR errTp;
HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle; HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle;
err = mpegSurroundDecoder_Config( err = mpegSurroundDecoder_Config(
(CMpegSurroundDecoder *)hAacDecoder->pMpegSurroundDecoder, hBs, coreCodec, (CMpegSurroundDecoder *)hAacDecoder->pMpegSurroundDecoder, hBs, coreCodec,
samplingRate, frameSize, stereoConfigIndex, coreSbrFrameLengthIndex, samplingRate, frameSize, numChannels, stereoConfigIndex,
configBytes, configMode, configChanged); coreSbrFrameLengthIndex, configBytes, configMode, configChanged);
switch (err) { switch (err) {
case MPS_UNSUPPORTED_CONFIG: case MPS_UNSUPPORTED_CONFIG:
@ -443,12 +441,23 @@ static INT aacDecoder_UniDrcCallback(void *handle, HANDLE_FDK_BITSTREAM hBs,
TRANSPORTDEC_ERROR errTp; TRANSPORTDEC_ERROR errTp;
HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle; HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle;
DRC_DEC_CODEC_MODE drcDecCodecMode = DRC_DEC_CODEC_MODE_UNDEFINED; DRC_DEC_CODEC_MODE drcDecCodecMode = DRC_DEC_CODEC_MODE_UNDEFINED;
UCHAR dummyBuffer[4] = {0};
FDK_BITSTREAM dummyBs;
HANDLE_FDK_BITSTREAM hReadBs;
if (subStreamIndex != 0) { if (subStreamIndex != 0) {
return TRANSPORTDEC_OK; return TRANSPORTDEC_OK;
} }
else if (aot == AOT_USAC) { if (hBs == NULL) {
/* use dummy zero payload to clear memory */
hReadBs = &dummyBs;
FDKinitBitStream(hReadBs, dummyBuffer, 4, 24);
} else {
hReadBs = hBs;
}
if (aot == AOT_USAC) {
drcDecCodecMode = DRC_DEC_MPEG_D_USAC; drcDecCodecMode = DRC_DEC_MPEG_D_USAC;
} }
@ -457,10 +466,10 @@ static INT aacDecoder_UniDrcCallback(void *handle, HANDLE_FDK_BITSTREAM hBs,
if (payloadType == 0) /* uniDrcConfig */ if (payloadType == 0) /* uniDrcConfig */
{ {
err = FDK_drcDec_ReadUniDrcConfig(hAacDecoder->hUniDrcDecoder, hBs); err = FDK_drcDec_ReadUniDrcConfig(hAacDecoder->hUniDrcDecoder, hReadBs);
} else /* loudnessInfoSet */ } else /* loudnessInfoSet */
{ {
err = FDK_drcDec_ReadLoudnessInfoSet(hAacDecoder->hUniDrcDecoder, hBs); err = FDK_drcDec_ReadLoudnessInfoSet(hAacDecoder->hUniDrcDecoder, hReadBs);
hAacDecoder->loudnessInfoSetPosition[1] = payloadStart; hAacDecoder->loudnessInfoSetPosition[1] = payloadStart;
hAacDecoder->loudnessInfoSetPosition[2] = fullPayloadLength; hAacDecoder->loudnessInfoSetPosition[2] = fullPayloadLength;
} }
@ -822,6 +831,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_SetParam(
case AAC_DRC_ATTENUATION_FACTOR: case AAC_DRC_ATTENUATION_FACTOR:
/* DRC compression factor (where 0 is no and 127 is max compression) */ /* DRC compression factor (where 0 is no and 127 is max compression) */
if ((value < 0) || (value > 127)) {
return AAC_DEC_SET_PARAM_FAIL;
}
errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_CUT_SCALE, value); errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_CUT_SCALE, value);
uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_COMPRESS, uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_COMPRESS,
value * (FL2FXCONST_DBL(0.5f / 127.0f))); value * (FL2FXCONST_DBL(0.5f / 127.0f)));
@ -829,6 +841,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_SetParam(
case AAC_DRC_BOOST_FACTOR: case AAC_DRC_BOOST_FACTOR:
/* DRC boost factor (where 0 is no and 127 is max boost) */ /* DRC boost factor (where 0 is no and 127 is max boost) */
if ((value < 0) || (value > 127)) {
return AAC_DEC_SET_PARAM_FAIL;
}
errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BOOST_SCALE, value); errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BOOST_SCALE, value);
uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_BOOST, uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_BOOST,
value * (FL2FXCONST_DBL(0.5f / 127.0f))); value * (FL2FXCONST_DBL(0.5f / 127.0f)));
@ -1151,6 +1166,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
int applyCrossfade = 1; /* flag indicates if flushing was possible */ int applyCrossfade = 1; /* flag indicates if flushing was possible */
PCM_DEC *pTimeData2; PCM_DEC *pTimeData2;
PCM_AAC *pTimeData3; PCM_AAC *pTimeData3;
INT pcmLimiterScale = 0;
INT interleaved = 0;
if (self == NULL) { if (self == NULL) {
return AAC_DEC_INVALID_HANDLE; return AAC_DEC_INVALID_HANDLE;
@ -1173,10 +1190,12 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
aacDecoder_FreeMemCallback(self, &asc); aacDecoder_FreeMemCallback(self, &asc);
self->streamInfo.numChannels = 0; self->streamInfo.numChannels = 0;
/* 3) restore AudioSpecificConfig */ /* 3) restore AudioSpecificConfig */
if (asc.configBits <= (TP_USAC_MAX_CONFIG_LEN << 3)) {
transportDec_OutOfBandConfig(self->hInput, asc.config, transportDec_OutOfBandConfig(self->hInput, asc.config,
(asc.configBits + 7) >> 3, 0); (asc.configBits + 7) >> 3, 0);
} }
} }
}
if (!((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) || if (!((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) ||
(self->flushStatus == AACDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) || (self->flushStatus == AACDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
@ -1607,6 +1626,11 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
/* set params */ /* set params */
sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY, sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY,
self->sbrParams.bsDelay); self->sbrParams.bsDelay);
sbrDecoder_SetParam(
self->hSbrDecoder, SBR_FLUSH_DATA,
(flags & AACDEC_FLUSH) |
((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
: 0));
sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1); sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1);
@ -1794,8 +1818,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
} }
if (self->streamInfo.extAot != AOT_AAC_SLS) { if (self->streamInfo.extAot != AOT_AAC_SLS) {
INT pcmLimiterScale = 0; interleaved = 0;
INT interleaved = 0;
interleaved |= (self->sbrEnabled) ? 1 : 0; interleaved |= (self->sbrEnabled) ? 1 : 0;
interleaved |= (self->mpsEnableCurr) ? 1 : 0; interleaved |= (self->mpsEnableCurr) ? 1 : 0;
PCMDMX_ERROR dmxErr = PCMDMX_OK; PCMDMX_ERROR dmxErr = PCMDMX_OK;
@ -1826,7 +1849,80 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
* predictable behavior and thus maybe produce strange output. */ * predictable behavior and thus maybe produce strange output. */
ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
} }
}
if (self->flags[0] & AC_USAC) {
if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON &&
!(flags & AACDEC_CONCEAL)) {
CAacDecoder_PrepareCrossFade(pTimeData2, self->pTimeDataFlush,
self->streamInfo.numChannels,
self->streamInfo.frameSize, interleaved);
}
/* prepare crossfade buffer for fade in */
if (!applyCrossfade &&
(self->applyCrossfade != AACDEC_CROSSFADE_BITMASK_OFF) &&
!(flags & AACDEC_CONCEAL)) {
for (int ch = 0; ch < self->streamInfo.numChannels; ch++) {
for (int i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
self->pTimeDataFlush[ch][i] = (PCM_DEC)0;
}
}
applyCrossfade = 1;
}
if (applyCrossfade &&
(self->applyCrossfade != AACDEC_CROSSFADE_BITMASK_OFF) &&
!(accessUnit < numPrerollAU) &&
(self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
CAacDecoder_ApplyCrossFade(pTimeData2, self->pTimeDataFlush,
self->streamInfo.numChannels,
self->streamInfo.frameSize, interleaved);
self->applyCrossfade =
AACDEC_CROSSFADE_BITMASK_OFF; /* disable cross-fade between frames
at nect config change */
}
}
/* Signal interruption to take effect in next frame. */
if ((flags & AACDEC_FLUSH || self->flushStatus) &&
!(flags & AACDEC_CONCEAL)) {
aacDecoder_SignalInterruption(self);
}
/* Update externally visible copy of flags */
self->streamInfo.flags = self->flags[0];
} /* USAC DASH IPF flushing possible end */
if (accessUnit < numPrerollAU) {
FDKpushBack(hBsAu, auStartAnchor - (INT)FDKgetValidBits(hBsAu));
} else {
if ((self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON) ||
(self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON_IN_BAND) ||
(self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
self->buildUpCnt--;
if (self->buildUpCnt < 0) {
self->buildUpStatus = 0;
}
}
if (self->flags[0] & AC_USAC) {
if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON &&
!(flags & AACDEC_CONCEAL)) {
self->streamInfo.frameSize = 0;
}
}
}
if (self->flushStatus != AACDEC_USAC_DASH_IPF_FLUSH_ON) {
accessUnit++;
}
} while ((accessUnit < numAccessUnits) ||
((self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) &&
!(flags & AACDEC_CONCEAL)));
if (self->streamInfo.extAot != AOT_AAC_SLS) {
pcmLimiterScale += PCM_OUT_HEADROOM; pcmLimiterScale += PCM_OUT_HEADROOM;
if (flags & AACDEC_CLRHIST) { if (flags & AACDEC_CLRHIST) {
@ -1838,14 +1934,12 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
} }
} }
/* Set applyExtGain if DRC processing is enabled and if /* Set applyExtGain if DRC processing is enabled and if progRefLevelPresent
progRefLevelPresent is present for the first time. Consequences: The is present for the first time. Consequences: The headroom of the output
headroom of the output signal can be set to AACDEC_DRC_GAIN_SCALING signal can be set to AACDEC_DRC_GAIN_SCALING only for audio formats which
only for audio formats which support legacy DRC Level Normalization. support legacy DRC Level Normalization. For all other audio formats the
For all other audio formats the headroom of the output headroom of the output signal is set to PCM_OUT_HEADROOM. */
signal is set to PCM_OUT_HEADROOM. */ if (self->hDrcInfo->enable && (self->hDrcInfo->progRefLevelPresent == 1)) {
if (self->hDrcInfo->enable &&
(self->hDrcInfo->progRefLevelPresent == 1)) {
self->hDrcInfo->applyExtGain |= 1; self->hDrcInfo->applyExtGain |= 1;
} }
@ -1906,8 +2000,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
} else { } else {
if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) { if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) {
pcmLimiterScale = applyDrcLevelNormalization( pcmLimiterScale = applyDrcLevelNormalization(
self->hDrcInfo, pTimeData2, self->extGain, NULL, self->hDrcInfo, pTimeData2, self->extGain, NULL, pcmLimiterScale,
pcmLimiterScale, self->extGainDelay, self->streamInfo.frameSize, self->extGainDelay, self->streamInfo.frameSize,
self->streamInfo.numChannels, self->streamInfo.numChannels,
(interleaved || (self->streamInfo.numChannels == 1)) (interleaved || (self->streamInfo.numChannels == 1))
? 1 ? 1
@ -1915,9 +2009,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
0); 0);
} }
/* If numChannels = 1 we do not need interleaving. The same applies if /* If numChannels = 1 we do not need interleaving. The same applies if SBR
SBR or MPS are used, since their output is interleaved already or MPS are used, since their output is interleaved already (resampled or
(resampled or not) */ not) */
if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) || if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
(self->mpsEnableCurr)) { (self->mpsEnableCurr)) {
scaleValuesSaturate( scaleValuesSaturate(
@ -1932,80 +2026,12 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
pcmLimiterScale); pcmLimiterScale);
/* Interleave ouput buffer */ /* Interleave ouput buffer */
FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData, FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData,
self->streamInfo.numChannels, self->streamInfo.numChannels, self->streamInfo.frameSize,
self->streamInfo.frameSize,
self->streamInfo.frameSize); self->streamInfo.frameSize);
} }
} }
} /* if (self->streamInfo.extAot != AOT_AAC_SLS)*/ } /* if (self->streamInfo.extAot != AOT_AAC_SLS)*/
if (self->flags[0] & AC_USAC) {
if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON &&
!(flags & AACDEC_CONCEAL)) {
CAacDecoder_PrepareCrossFade(pTimeData, self->pTimeDataFlush,
self->streamInfo.numChannels,
self->streamInfo.frameSize, 1);
}
/* prepare crossfade buffer for fade in */
if (!applyCrossfade && self->applyCrossfade &&
!(flags & AACDEC_CONCEAL)) {
for (int ch = 0; ch < self->streamInfo.numChannels; ch++) {
for (int i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
self->pTimeDataFlush[ch][i] = 0;
}
}
applyCrossfade = 1;
}
if (applyCrossfade && self->applyCrossfade &&
!(accessUnit < numPrerollAU) &&
(self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
CAacDecoder_ApplyCrossFade(pTimeData, self->pTimeDataFlush,
self->streamInfo.numChannels,
self->streamInfo.frameSize, 1);
self->applyCrossfade = 0;
}
}
/* Signal interruption to take effect in next frame. */
if ((flags & AACDEC_FLUSH || self->flushStatus) &&
!(flags & AACDEC_CONCEAL)) {
aacDecoder_SignalInterruption(self);
}
/* Update externally visible copy of flags */
self->streamInfo.flags = self->flags[0];
} /* USAC DASH IPF flushing possible end */
if (accessUnit < numPrerollAU) {
FDKpushBack(hBsAu, auStartAnchor - (INT)FDKgetValidBits(hBsAu));
} else {
if ((self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON) ||
(self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON_IN_BAND) ||
(self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
self->buildUpCnt--;
if (self->buildUpCnt < 0) {
self->buildUpStatus = 0;
}
}
if (self->flags[0] & AC_USAC) {
if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON &&
!(flags & AACDEC_CONCEAL)) {
self->streamInfo.frameSize = 0;
}
}
}
if (self->flushStatus != AACDEC_USAC_DASH_IPF_FLUSH_ON) {
accessUnit++;
}
} while ((accessUnit < numAccessUnits) ||
((self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) &&
!(flags & AACDEC_CONCEAL)));
bail: bail:
/* error in renderer part occurred, ErrorStatus was set to invalid output */ /* error in renderer part occurred, ErrorStatus was set to invalid output */

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -265,7 +265,9 @@ void CChannelElement_Decode(
stereo prediction since scaling has already been carried out. */ stereo prediction since scaling has already been carried out. */
int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste); int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);
if ((!CP_active) || (CP_active && (max_sfb_ste < noSfbs)) || if (!(CP_active && (max_sfb_ste == noSfbs)) ||
!(CP_active &&
!(pAacDecoderChannelInfo[ch]->pDynData->TnsData.Active)) ||
((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) && ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
(pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr == (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
0))) { 0))) {

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -628,7 +628,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd; SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd;
SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc; SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
UCHAR *pEscEscCnt = &(pRvlc->numDecodedEscapeWordsEsc); UCHAR escEscCnt = pRvlc->numDecodedEscapeWordsEsc;
UCHAR *pEscBwdCnt = &(pRvlc->numDecodedEscapeWordsBwd); UCHAR *pEscBwdCnt = &(pRvlc->numDecodedEscapeWordsBwd);
pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_bwd); pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_bwd);
@ -636,7 +636,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
*pEscBwdCnt = 0; *pEscBwdCnt = 0;
pRvlc->direction = BWD; pRvlc->direction = BWD;
pScfEsc += *pEscEscCnt - 1; /* set pScfEsc to last entry */ pScfEsc += escEscCnt - 1; /* set pScfEsc to last entry */
pRvlc->firstScf = 0; pRvlc->firstScf = 0;
pRvlc->firstNrg = 0; pRvlc->firstNrg = 0;
pRvlc->firstIs = 0; pRvlc->firstIs = 0;
@ -651,7 +651,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
} }
dpcm -= TABLE_OFFSET; dpcm -= TABLE_OFFSET;
if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
if (pRvlc->length_of_rvlc_escapes) { if ((pRvlc->length_of_rvlc_escapes) || (*pEscBwdCnt >= escEscCnt)) {
pRvlc->conceal_min = bnds; pRvlc->conceal_min = bnds;
return; return;
} else { } else {
@ -694,7 +694,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
} }
dpcm -= TABLE_OFFSET; dpcm -= TABLE_OFFSET;
if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
if (pRvlc->length_of_rvlc_escapes) { if ((pRvlc->length_of_rvlc_escapes) || (*pEscBwdCnt >= escEscCnt)) {
pScfBwd[bnds] = position; pScfBwd[bnds] = position;
pRvlc->conceal_min = fMax(0, bnds - offset); pRvlc->conceal_min = fMax(0, bnds - offset);
return; return;
@ -731,7 +731,8 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
} }
dpcm -= TABLE_OFFSET; dpcm -= TABLE_OFFSET;
if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
if (pRvlc->length_of_rvlc_escapes) { if ((pRvlc->length_of_rvlc_escapes) ||
(*pEscBwdCnt >= escEscCnt)) {
pScfBwd[bnds] = noisenrg; pScfBwd[bnds] = noisenrg;
pRvlc->conceal_min = fMax(0, bnds - offset); pRvlc->conceal_min = fMax(0, bnds - offset);
return; return;
@ -762,7 +763,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
} }
dpcm -= TABLE_OFFSET; dpcm -= TABLE_OFFSET;
if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
if (pRvlc->length_of_rvlc_escapes) { if ((pRvlc->length_of_rvlc_escapes) || (*pEscBwdCnt >= escEscCnt)) {
pScfBwd[bnds] = factor; pScfBwd[bnds] = factor;
pRvlc->conceal_min = fMax(0, bnds - offset); pRvlc->conceal_min = fMax(0, bnds - offset);
return; return;

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -719,7 +719,7 @@ static void ConcealPitchLag(CAcelpStaticMem *acelp_mem, const int PIT_MAX,
UCHAR *pold_T0_frac = &acelp_mem->old_T0_frac; UCHAR *pold_T0_frac = &acelp_mem->old_T0_frac;
if ((int)*pold_T0 >= PIT_MAX) { if ((int)*pold_T0 >= PIT_MAX) {
*pold_T0 = (UCHAR)(PIT_MAX - 5); *pold_T0 = (USHORT)(PIT_MAX - 5);
} }
*pT0 = (int)*pold_T0; *pT0 = (int)*pold_T0;
*pT0_frac = (int)*pold_T0_frac; *pT0_frac = (int)*pold_T0_frac;

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -1643,7 +1643,7 @@ AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder,
* *
* \return * \return
* - AACENC_OK, on succes. * - AACENC_OK, on succes.
* - AACENC_INIT_ERROR, on failure. * - AACENC_INVALID_HANDLE, AACENC_INIT_ERROR, on failure.
*/ */
AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER hAacEncoder, AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER hAacEncoder,
AACENC_InfoStruct *pInfo); AACENC_InfoStruct *pInfo);

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -1242,7 +1242,7 @@ static INT aacenc_SbrCallback(void *self, HANDLE_FDK_BITSTREAM hBs,
INT aacenc_SscCallback(void *self, HANDLE_FDK_BITSTREAM hBs, INT aacenc_SscCallback(void *self, HANDLE_FDK_BITSTREAM hBs,
const AUDIO_OBJECT_TYPE coreCodec, const AUDIO_OBJECT_TYPE coreCodec,
const INT samplingRate, const INT frameSize, const INT samplingRate, const INT frameSize,
const INT stereoConfigIndex, const INT numChannels, const INT stereoConfigIndex,
const INT coreSbrFrameLengthIndex, const INT configBytes, const INT coreSbrFrameLengthIndex, const INT configBytes,
const UCHAR configMode, UCHAR *configChanged) { const UCHAR configMode, UCHAR *configChanged) {
HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self; HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self;
@ -1784,8 +1784,8 @@ AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder,
hAacEncoder->nSamplesRead)); hAacEncoder->nSamplesRead));
INT_PCM *pIn = INT_PCM *pIn =
hAacEncoder->inputBuffer + hAacEncoder->inputBuffer +
(hAacEncoder->inputBufferOffset + hAacEncoder->nSamplesRead) / hAacEncoder->inputBufferOffset / hAacEncoder->aacConfig.nChannels +
hAacEncoder->aacConfig.nChannels; hAacEncoder->nSamplesRead / hAacEncoder->extParam.nChannels;
newSamples -= newSamples -=
(newSamples % (newSamples %
hAacEncoder->extParam hAacEncoder->extParam
@ -1827,12 +1827,13 @@ AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder,
/* clear out until end-of-buffer */ /* clear out until end-of-buffer */
if (nZeros) { if (nZeros) {
INT_PCM *pIn =
hAacEncoder->inputBuffer +
hAacEncoder->inputBufferOffset /
hAacEncoder->aacConfig.nChannels +
hAacEncoder->nSamplesRead / hAacEncoder->extParam.nChannels;
for (i = 0; i < (int)hAacEncoder->extParam.nChannels; i++) { for (i = 0; i < (int)hAacEncoder->extParam.nChannels; i++) {
FDKmemclear(hAacEncoder->inputBuffer + FDKmemclear(pIn + i * hAacEncoder->inputBufferSizePerChannel,
i * hAacEncoder->inputBufferSizePerChannel +
(hAacEncoder->inputBufferOffset +
hAacEncoder->nSamplesRead) /
hAacEncoder->extParam.nChannels,
sizeof(INT_PCM) * nZeros); sizeof(INT_PCM) * nZeros);
} }
hAacEncoder->nZerosAppended += nZeros; hAacEncoder->nZerosAppended += nZeros;
@ -2520,6 +2521,11 @@ AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER hAacEncoder,
AACENC_InfoStruct *pInfo) { AACENC_InfoStruct *pInfo) {
AACENC_ERROR err = AACENC_OK; AACENC_ERROR err = AACENC_OK;
if ((hAacEncoder == NULL) || (pInfo == NULL)) {
err = AACENC_INVALID_HANDLE;
goto bail;
}
FDKmemclear(pInfo, sizeof(AACENC_InfoStruct)); FDKmemclear(pInfo, sizeof(AACENC_InfoStruct));
pInfo->confSize = 64; /* pre-initialize */ pInfo->confSize = 64; /* pre-initialize */

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -512,11 +512,14 @@ drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,
fMin(tmpNNodes, (UCHAR)16) * sizeof(GAIN_NODE)); fMin(tmpNNodes, (UCHAR)16) * sizeof(GAIN_NODE));
} }
if (pCoef && (gainSequenceCount ==
pCoef->gainSequenceCount)) { /* all sequences have been read */
hUniDrcGain->uniDrcGainExtPresent = FDKreadBits(hBs, 1); hUniDrcGain->uniDrcGainExtPresent = FDKreadBits(hBs, 1);
if (hUniDrcGain->uniDrcGainExtPresent == 1) { if (hUniDrcGain->uniDrcGainExtPresent == 1) {
err = _readUniDrcGainExtension(hBs, &(hUniDrcGain->uniDrcGainExtension)); err = _readUniDrcGainExtension(hBs, &(hUniDrcGain->uniDrcGainExtension));
if (err) return err; if (err) return err;
} }
}
if (err == DE_OK && gainSequenceCount > 0) { if (err == DE_OK && gainSequenceCount > 0) {
hUniDrcGain->status = 1; hUniDrcGain->status = 1;
@ -914,7 +917,7 @@ static void _skipEqCoefficients(HANDLE_FDK_BITSTREAM hBs) {
firFilterOrder; firFilterOrder;
int uniqueEqSubbandGainsCount, eqSubbandGainRepresentation, int uniqueEqSubbandGainsCount, eqSubbandGainRepresentation,
eqSubbandGainCount; eqSubbandGainCount;
EQ_SUBBAND_GAIN_FORMAT eqSubbandGainFormat; int eqSubbandGainFormat;
eqDelayMaxPresent = FDKreadBits(hBs, 1); eqDelayMaxPresent = FDKreadBits(hBs, 1);
if (eqDelayMaxPresent) { if (eqDelayMaxPresent) {
@ -955,7 +958,7 @@ static void _skipEqCoefficients(HANDLE_FDK_BITSTREAM hBs) {
uniqueEqSubbandGainsCount = FDKreadBits(hBs, 6); uniqueEqSubbandGainsCount = FDKreadBits(hBs, 6);
if (uniqueEqSubbandGainsCount > 0) { if (uniqueEqSubbandGainsCount > 0) {
eqSubbandGainRepresentation = FDKreadBits(hBs, 1); eqSubbandGainRepresentation = FDKreadBits(hBs, 1);
eqSubbandGainFormat = (EQ_SUBBAND_GAIN_FORMAT)FDKreadBits(hBs, 4); eqSubbandGainFormat = FDKreadBits(hBs, 4);
switch (eqSubbandGainFormat) { switch (eqSubbandGainFormat) {
case GF_QMF32: case GF_QMF32:
eqSubbandGainCount = 32; eqSubbandGainCount = 32;

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -159,9 +159,6 @@ typedef enum {
#ifndef HUFFDEC_PARAMS #ifndef HUFFDEC_PARAMS
#define HUFFDEC_PARMS #define HUFFDEC_PARMS
#define PAIR_SHIFT 4
#define PAIR_MASK 0xf
#define MAX_ENTRIES 168 #define MAX_ENTRIES 168
#define HANDLE_HUFF_NODE const SHORT(*)[MAX_ENTRIES][2] #define HANDLE_HUFF_NODE const SHORT(*)[MAX_ENTRIES][2]

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -539,11 +539,11 @@ static void dualChannelFiltering(const FIXP_DBL *const pQmfReal,
i6 = pQmfImag[pReadIdx[6]] >> 2; i6 = pQmfImag[pReadIdx[6]] >> 2;
FDK_ASSERT((invert == 0) || (invert == 1)); FDK_ASSERT((invert == 0) || (invert == 1));
mHybridReal[0 + invert] = (r6 + r1) << 1; mHybridReal[0 + invert] = SATURATE_LEFT_SHIFT((r6 + r1), 1, DFRACT_BITS);
mHybridImag[0 + invert] = (i6 + i1) << 1; mHybridImag[0 + invert] = SATURATE_LEFT_SHIFT((i6 + i1), 1, DFRACT_BITS);
mHybridReal[1 - invert] = (r6 - r1) << 1; mHybridReal[1 - invert] = SATURATE_LEFT_SHIFT((r6 - r1), 1, DFRACT_BITS);
mHybridImag[1 - invert] = (i6 - i1) << 1; mHybridImag[1 - invert] = SATURATE_LEFT_SHIFT((i6 - i1), 1, DFRACT_BITS);
} }
static void fourChannelFiltering(const FIXP_DBL *const pQmfReal, static void fourChannelFiltering(const FIXP_DBL *const pQmfReal,
@ -766,15 +766,15 @@ static void eightChannelFiltering(const FIXP_DBL *const pQmfReal,
mHybridReal[3] = pfft[FFT_IDX_R(1)] << sc; mHybridReal[3] = pfft[FFT_IDX_R(1)] << sc;
mHybridImag[3] = pfft[FFT_IDX_I(1)] << sc; mHybridImag[3] = pfft[FFT_IDX_I(1)] << sc;
mHybridReal[4] = pfft[FFT_IDX_R(2)] << sc; mHybridReal[4] = SATURATE_LEFT_SHIFT(
mHybridReal[4] += pfft[FFT_IDX_R(5)] << sc; (pfft[FFT_IDX_R(2)] + pfft[FFT_IDX_R(5)]), sc, DFRACT_BITS);
mHybridImag[4] = pfft[FFT_IDX_I(2)] << sc; mHybridImag[4] = SATURATE_LEFT_SHIFT(
mHybridImag[4] += pfft[FFT_IDX_I(5)] << sc; (pfft[FFT_IDX_I(2)] + pfft[FFT_IDX_I(5)]), sc, DFRACT_BITS);
mHybridReal[5] = pfft[FFT_IDX_R(3)] << sc; mHybridReal[5] = SATURATE_LEFT_SHIFT(
mHybridReal[5] += pfft[FFT_IDX_R(4)] << sc; (pfft[FFT_IDX_R(3)] + pfft[FFT_IDX_R(4)]), sc, DFRACT_BITS);
mHybridImag[5] = pfft[FFT_IDX_I(3)] << sc; mHybridImag[5] = SATURATE_LEFT_SHIFT(
mHybridImag[5] += pfft[FFT_IDX_I(4)] << sc; (pfft[FFT_IDX_I(3)] + pfft[FFT_IDX_I(4)]), sc, DFRACT_BITS);
} else { } else {
for (k = 0; k < 8; k++) { for (k = 0; k < 8; k++) {
mHybridReal[k] = pfft[FFT_IDX_R(k)] << sc; mHybridReal[k] = pfft[FFT_IDX_R(k)] << sc;

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -102,11 +102,6 @@ amm-info@iis.fraunhofer.de
#include "autocorr2nd.h" #include "autocorr2nd.h"
/* If the accumulator does not provide enough overflow bits,
products have to be shifted down in the autocorrelation below. */
#define SHIFT_FACTOR (5)
#define SHIFT >> (SHIFT_FACTOR)
/*! /*!
* *
* \brief Calculate second order autocorrelation using 2 accumulators * \brief Calculate second order autocorrelation using 2 accumulators
@ -126,45 +121,49 @@ INT autoCorr2nd_real(
const FIXP_DBL *realBuf = reBuffer; const FIXP_DBL *realBuf = reBuffer;
const int len_scale = fMax(DFRACT_BITS - fNormz((FIXP_DBL)(len / 2)), 1);
/* /*
r11r,r22r r11r,r22r
r01r,r12r r01r,r12r
r02r r02r
*/ */
pReBuf = realBuf - 2; pReBuf = realBuf - 2;
accu5 = ((fMultDiv2(pReBuf[0], pReBuf[2]) + fMultDiv2(pReBuf[1], pReBuf[3])) accu5 =
SHIFT); ((fMultDiv2(pReBuf[0], pReBuf[2]) + fMultDiv2(pReBuf[1], pReBuf[3])) >>
len_scale);
pReBuf++; pReBuf++;
/* len must be even */ /* len must be even */
accu1 = fPow2Div2(pReBuf[0]) SHIFT; accu1 = fPow2Div2(pReBuf[0]) >> len_scale;
accu3 = fMultDiv2(pReBuf[0], pReBuf[1]) SHIFT; accu3 = fMultDiv2(pReBuf[0], pReBuf[1]) >> len_scale;
pReBuf++; pReBuf++;
for (j = (len - 2) >> 1; j != 0; j--, pReBuf += 2) { for (j = (len - 2) >> 1; j != 0; j--, pReBuf += 2) {
accu1 += ((fPow2Div2(pReBuf[0]) + fPow2Div2(pReBuf[1])) SHIFT); accu1 += ((fPow2Div2(pReBuf[0]) + fPow2Div2(pReBuf[1])) >> len_scale);
accu3 += ((fMultDiv2(pReBuf[0], pReBuf[1]) + accu3 +=
fMultDiv2(pReBuf[1], pReBuf[2])) SHIFT); ((fMultDiv2(pReBuf[0], pReBuf[1]) + fMultDiv2(pReBuf[1], pReBuf[2])) >>
len_scale);
accu5 += ((fMultDiv2(pReBuf[0], pReBuf[2]) + accu5 +=
fMultDiv2(pReBuf[1], pReBuf[3])) SHIFT); ((fMultDiv2(pReBuf[0], pReBuf[2]) + fMultDiv2(pReBuf[1], pReBuf[3])) >>
len_scale);
} }
accu2 = (fPow2Div2(realBuf[-2]) SHIFT); accu2 = (fPow2Div2(realBuf[-2]) >> len_scale);
accu2 += accu1; accu2 += accu1;
accu1 += (fPow2Div2(realBuf[len - 2]) SHIFT); accu1 += (fPow2Div2(realBuf[len - 2]) >> len_scale);
accu4 = (fMultDiv2(realBuf[-1], realBuf[-2]) SHIFT); accu4 = (fMultDiv2(realBuf[-1], realBuf[-2]) >> len_scale);
accu4 += accu3; accu4 += accu3;
accu3 += (fMultDiv2(realBuf[len - 1], realBuf[len - 2]) SHIFT); accu3 += (fMultDiv2(realBuf[len - 1], realBuf[len - 2]) >> len_scale);
mScale = CntLeadingZeros( mScale = CntLeadingZeros(
(accu1 | accu2 | fAbs(accu3) | fAbs(accu4) | fAbs(accu5))) - (accu1 | accu2 | fAbs(accu3) | fAbs(accu4) | fAbs(accu5))) -
1; 1;
autoCorrScaling = mScale - 1 - SHIFT_FACTOR; /* -1 because of fMultDiv2*/ autoCorrScaling = mScale - 1 - len_scale; /* -1 because of fMultDiv2*/
/* Scale to common scale factor */ /* Scale to common scale factor */
ac->r11r = accu1 << mScale; ac->r11r = accu1 << mScale;
@ -190,7 +189,7 @@ INT autoCorr2nd_cplx(
const FIXP_DBL *imBuffer, /*!< Pointer to imag part of input samples */ const FIXP_DBL *imBuffer, /*!< Pointer to imag part of input samples */
const int len /*!< Number of input samples (should be smaller than 128) */ const int len /*!< Number of input samples (should be smaller than 128) */
) { ) {
int j, autoCorrScaling, mScale, len_scale; int j, autoCorrScaling, mScale;
FIXP_DBL accu0, accu1, accu2, accu3, accu4, accu5, accu6, accu7, accu8; FIXP_DBL accu0, accu1, accu2, accu3, accu4, accu5, accu6, accu7, accu8;
@ -199,7 +198,7 @@ INT autoCorr2nd_cplx(
const FIXP_DBL *realBuf = reBuffer; const FIXP_DBL *realBuf = reBuffer;
const FIXP_DBL *imagBuf = imBuffer; const FIXP_DBL *imagBuf = imBuffer;
(len > 64) ? (len_scale = 6) : (len_scale = 5); const int len_scale = fMax(DFRACT_BITS - fNormz((FIXP_DBL)len), 1);
/* /*
r00r, r00r,
r11r,r22r r11r,r22r

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -305,9 +305,8 @@ void dct_II(
{ {
for (i = 0; i < M; i++) { for (i = 0; i < M; i++) {
tmp[i] = pDat[2 * i] >> 1; /* dit_fft expects 1 bit scaled input values */ tmp[i] = pDat[2 * i] >> 2;
tmp[L - 1 - i] = tmp[L - 1 - i] = pDat[2 * i + 1] >> 2;
pDat[2 * i + 1] >> 1; /* dit_fft expects 1 bit scaled input values */
} }
} }
@ -337,15 +336,14 @@ void dct_II(
a1 = ((pTmp_0[0] >> 1) + (pTmp_1[0] >> 1)); a1 = ((pTmp_0[0] >> 1) + (pTmp_1[0] >> 1));
a2 = ((pTmp_0[1] >> 1) - (pTmp_1[1] >> 1)); a2 = ((pTmp_0[1] >> 1) - (pTmp_1[1] >> 1));
cplxMultDiv2(&accu3, &accu4, (a1 + accu2), -(accu1 + a2), cplxMult(&accu3, &accu4, (accu1 + a2), (a1 + accu2), sin_twiddle[i * inc]);
sin_twiddle[i * inc]); pDat[L - i] = -accu3;
pDat[L - i] = accu4; pDat[i] = accu4;
pDat[i] = accu3;
cplxMultDiv2(&accu3, &accu4, (a1 - accu2), -(accu1 - a2), cplxMult(&accu3, &accu4, (accu1 - a2), (a1 - accu2),
sin_twiddle[(M - i) * inc]); sin_twiddle[(M - i) * inc]);
pDat[M + i] = accu4; pDat[M + i] = -accu3;
pDat[M - i] = accu3; pDat[M - i] = accu4;
/* Create index helper variables for (4*i)*inc indexed equivalent values of /* Create index helper variables for (4*i)*inc indexed equivalent values of
* short tables. */ * short tables. */
@ -356,12 +354,12 @@ void dct_II(
} }
} }
cplxMultDiv2(&accu1, &accu2, tmp[M], tmp[M + 1], sin_twiddle[(M / 2) * inc]); cplxMult(&accu1, &accu2, tmp[M], tmp[M + 1], sin_twiddle[(M / 2) * inc]);
pDat[L - (M / 2)] = accu2; pDat[L - (M / 2)] = accu2;
pDat[M / 2] = accu1; pDat[M / 2] = accu1;
pDat[0] = (tmp[0] >> 1) + (tmp[1] >> 1); pDat[0] = tmp[0] + tmp[1];
pDat[M] = fMult(((tmp[0] >> 1) - (tmp[1] >> 1)), pDat[M] = fMult(tmp[0] - tmp[1],
sin_twiddle[M * inc].v.re); /* cos((PI/(2*L))*M); */ sin_twiddle[M * inc].v.re); /* cos((PI/(2*L))*M); */
*pDat_e += 2; *pDat_e += 2;

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -568,12 +568,12 @@ bail:
static ERROR_t huff_decode(HANDLE_FDK_BITSTREAM strm, SCHAR* out_data_1, static ERROR_t huff_decode(HANDLE_FDK_BITSTREAM strm, SCHAR* out_data_1,
SCHAR* out_data_2, DATA_TYPE data_type, SCHAR* out_data_2, DATA_TYPE data_type,
DIFF_TYPE diff_type_1, DIFF_TYPE diff_type_2, DIFF_TYPE diff_type_1, DIFF_TYPE diff_type_2,
int num_val, CODING_SCHEME* cdg_scheme, int ldMode) { int num_val, PAIRING* pairing_scheme, int ldMode) {
ERROR_t err = HUFFDEC_OK; ERROR_t err = HUFFDEC_OK;
CODING_SCHEME coding_scheme = HUFF_1D;
DIFF_TYPE diff_type; DIFF_TYPE diff_type;
int i = 0; int i = 0;
ULONG data = 0;
SCHAR pair_vec[28][2]; SCHAR pair_vec[28][2];
@ -596,15 +596,13 @@ static ERROR_t huff_decode(HANDLE_FDK_BITSTREAM strm, SCHAR* out_data_1,
int hufYY; int hufYY;
/* Coding scheme */ /* Coding scheme */
data = FDKreadBits(strm, 1); coding_scheme = (CODING_SCHEME)FDKreadBits(strm, 1);
*cdg_scheme = (CODING_SCHEME)(data << PAIR_SHIFT);
if (*cdg_scheme >> PAIR_SHIFT == HUFF_2D) { if (coding_scheme == HUFF_2D) {
if ((out_data_1 != NULL) && (out_data_2 != NULL) && (ldMode == 0)) { if ((out_data_1 != NULL) && (out_data_2 != NULL) && (ldMode == 0)) {
data = FDKreadBits(strm, 1); *pairing_scheme = (PAIRING)FDKreadBits(strm, 1);
*cdg_scheme = (CODING_SCHEME)(*cdg_scheme | data);
} else { } else {
*cdg_scheme = (CODING_SCHEME)(*cdg_scheme | FREQ_PAIR); *pairing_scheme = FREQ_PAIR;
} }
} }
@ -613,7 +611,7 @@ static ERROR_t huff_decode(HANDLE_FDK_BITSTREAM strm, SCHAR* out_data_1,
hufYY2 = diff_type_2; hufYY2 = diff_type_2;
} }
switch (*cdg_scheme >> PAIR_SHIFT) { switch (coding_scheme) {
case HUFF_1D: case HUFF_1D:
p0_flag[0] = (diff_type_1 == DIFF_FREQ); p0_flag[0] = (diff_type_1 == DIFF_FREQ);
p0_flag[1] = (diff_type_2 == DIFF_FREQ); p0_flag[1] = (diff_type_2 == DIFF_FREQ);
@ -634,7 +632,7 @@ static ERROR_t huff_decode(HANDLE_FDK_BITSTREAM strm, SCHAR* out_data_1,
case HUFF_2D: case HUFF_2D:
switch (*cdg_scheme & PAIR_MASK) { switch (*pairing_scheme) {
case FREQ_PAIR: case FREQ_PAIR:
if (out_data_1 != NULL) { if (out_data_1 != NULL) {
@ -843,7 +841,7 @@ ERROR_t EcDataPairDec(DECODER_TYPE DECODER, HANDLE_FDK_BITSTREAM strm,
SCHAR* pDataVec[2] = {NULL, NULL}; SCHAR* pDataVec[2] = {NULL, NULL};
DIFF_TYPE diff_type[2] = {DIFF_FREQ, DIFF_FREQ}; DIFF_TYPE diff_type[2] = {DIFF_FREQ, DIFF_FREQ};
CODING_SCHEME cdg_scheme = HUFF_1D; PAIRING pairing = FREQ_PAIR;
DIRECTION direction = BACKWARDS; DIRECTION direction = BACKWARDS;
switch (data_type) { switch (data_type) {
@ -959,7 +957,7 @@ ERROR_t EcDataPairDec(DECODER_TYPE DECODER, HANDLE_FDK_BITSTREAM strm,
} }
/* Huffman decoding */ /* Huffman decoding */
err = huff_decode(strm, pDataVec[0], pDataVec[1], data_type, diff_type[0], err = huff_decode(strm, pDataVec[0], pDataVec[1], data_type, diff_type[0],
diff_type[1], dataBands, &cdg_scheme, diff_type[1], dataBands, &pairing,
(DECODER == SAOC_DECODER)); (DECODER == SAOC_DECODER));
if (err != HUFFDEC_OK) { if (err != HUFFDEC_OK) {
return HUFFDEC_NOTOK; return HUFFDEC_NOTOK;
@ -986,8 +984,8 @@ ERROR_t EcDataPairDec(DECODER_TYPE DECODER, HANDLE_FDK_BITSTREAM strm,
} }
} }
mixed_time_pair = (diff_type[0] != diff_type[1]) && mixed_time_pair =
((cdg_scheme & PAIR_MASK) == TIME_PAIR); (diff_type[0] != diff_type[1]) && (pairing == TIME_PAIR);
if (direction == BACKWARDS) { if (direction == BACKWARDS) {
if (diff_type[0] == DIFF_FREQ) { if (diff_type[0] == DIFF_FREQ) {

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -368,7 +368,7 @@ typedef INT (*cbCtrlCFGChange_t)(void *, const CCtrlCFGChange *);
typedef INT (*cbSsc_t)(void *, HANDLE_FDK_BITSTREAM, typedef INT (*cbSsc_t)(void *, HANDLE_FDK_BITSTREAM,
const AUDIO_OBJECT_TYPE coreCodec, const AUDIO_OBJECT_TYPE coreCodec,
const INT samplingRate, const INT frameSize, const INT samplingRate, const INT frameSize,
const INT stereoConfigIndex, const INT numChannels, const INT stereoConfigIndex,
const INT coreSbrFrameLengthIndex, const INT configBytes, const INT coreSbrFrameLengthIndex, const INT configBytes,
const UCHAR configMode, UCHAR *configChanged); const UCHAR configMode, UCHAR *configChanged);

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -266,11 +266,118 @@ static int CProgramConfig_ReadHeightExt(CProgramConfig *pPce,
return (err); return (err);
} }
/**
* \brief Sanity checks for program config element.
* Check order of elements according to ISO/IEC 13818-7:2003(E),
* chapter 8.5.1
*
* \param pPce pointer to program config element.
*
* \return 0 if successful, otherwise 1.
*/
static int CProgramConfig_Check(CProgramConfig *pPce) {
INT i;
INT err = 0;
INT numBackChannels[3] = {0};
INT numSideChannels[3] = {0};
INT numFrontChannels[3] = {0};
UCHAR *pCpeFront = pPce->FrontElementIsCpe;
UCHAR *pCpeSide = pPce->SideElementIsCpe;
UCHAR *pCpeBack = pPce->BackElementIsCpe;
UCHAR *pHeight;
pHeight = pPce->BackElementHeightInfo;
for (i = 0; i < pPce->NumBackChannelElements; i++) {
numBackChannels[*pHeight] += pPce->BackElementIsCpe[i] ? 2 : 1;
pHeight++;
}
pHeight = pPce->SideElementHeightInfo;
for (i = 0; i < pPce->NumSideChannelElements; i++) {
numSideChannels[*pHeight] += pPce->SideElementIsCpe[i] ? 2 : 1;
pHeight++;
}
pHeight = pPce->FrontElementHeightInfo;
for (i = 0; i < pPce->NumFrontChannelElements; i++) {
numFrontChannels[*pHeight] += pPce->FrontElementIsCpe[i] ? 2 : 1;
pHeight++;
}
/* 0 = normal height channels, 1 = top height channels, 2 = bottom height
* channels */
for (i = 0; i < 3; i++) {
/* if number of channels is odd => first element must be a SCE (front center
* channel) */
if (numFrontChannels[i] & 1) {
if (*pCpeFront++ == ID_CPE) {
err = 1;
goto bail;
}
numFrontChannels[i]--;
}
while (numFrontChannels[i] > 0) {
/* must be CPE or paired SCE */
if (*pCpeFront++ == ID_SCE) {
if (*pCpeFront++ == ID_CPE) {
err = 1;
goto bail;
}
}
numFrontChannels[i] -= 2;
};
/* in case that a top center surround channel (Ts) is transmitted the number
* of channels can be odd */
if (i != 1) {
/* number of channels must be even */
if (numSideChannels[i] & 1) {
err = 1;
goto bail;
}
while (numSideChannels[i] > 0) {
/* must be CPE or paired SCE */
if (*pCpeSide++ == ID_SCE) {
if (*pCpeSide++ == ID_CPE) {
err = 1;
goto bail;
}
}
numSideChannels[i] -= 2;
};
}
while (numBackChannels[i] > 1) {
/* must be CPE or paired SCE */
if (*pCpeBack++ == ID_SCE) {
if (*pCpeBack++ == ID_CPE) {
err = 1;
goto bail;
}
}
numBackChannels[i] -= 2;
};
/* if number of channels is odd => last element must be a SCE (back center
* channel) */
if (numBackChannels[i]) {
if (*pCpeBack++ == ID_CPE) {
err = 1;
goto bail;
}
}
}
bail:
return err;
}
void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs, void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs,
UINT alignmentAnchor) { UINT alignmentAnchor) {
int i, err = 0; int i;
int commentBytes; int commentBytes;
UCHAR tag, isCpe;
UCHAR checkElementTagSelect[3][PC_FSB_CHANNELS_MAX] = {{0}};
pPce->isValid = 1;
pPce->NumEffectiveChannels = 0; pPce->NumEffectiveChannels = 0;
pPce->NumChannels = 0; pPce->NumChannels = 0;
pPce->ElementInstanceTag = (UCHAR)FDKreadBits(bs, 4); pPce->ElementInstanceTag = (UCHAR)FDKreadBits(bs, 4);
@ -297,28 +404,60 @@ void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs,
} }
for (i = 0; i < pPce->NumFrontChannelElements; i++) { for (i = 0; i < pPce->NumFrontChannelElements; i++) {
pPce->FrontElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1); pPce->FrontElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1);
pPce->FrontElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); pPce->FrontElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4);
pPce->NumChannels += pPce->FrontElementIsCpe[i] ? 2 : 1; pPce->NumChannels += pPce->FrontElementIsCpe[i] ? 2 : 1;
/* Check element instance tag according to ISO/IEC 13818-7:2003(E),
* chapter 8.2.1.1 */
if (checkElementTagSelect[isCpe][tag] == 0) {
checkElementTagSelect[isCpe][tag] = 1;
} else {
pPce->isValid = 0;
}
} }
for (i = 0; i < pPce->NumSideChannelElements; i++) { for (i = 0; i < pPce->NumSideChannelElements; i++) {
pPce->SideElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1); pPce->SideElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1);
pPce->SideElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); pPce->SideElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4);
pPce->NumChannels += pPce->SideElementIsCpe[i] ? 2 : 1; pPce->NumChannels += pPce->SideElementIsCpe[i] ? 2 : 1;
/* Check element instance tag according to ISO/IEC 13818-7:2003(E),
* chapter 8.2.1.1 */
if (checkElementTagSelect[isCpe][tag] == 0) {
checkElementTagSelect[isCpe][tag] = 1;
} else {
pPce->isValid = 0;
}
} }
for (i = 0; i < pPce->NumBackChannelElements; i++) { for (i = 0; i < pPce->NumBackChannelElements; i++) {
pPce->BackElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1); pPce->BackElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1);
pPce->BackElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); pPce->BackElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4);
pPce->NumChannels += pPce->BackElementIsCpe[i] ? 2 : 1; pPce->NumChannels += pPce->BackElementIsCpe[i] ? 2 : 1;
/* Check element instance tag according to ISO/IEC 13818-7:2003(E),
* chapter 8.2.1.1 */
if (checkElementTagSelect[isCpe][tag] == 0) {
checkElementTagSelect[isCpe][tag] = 1;
} else {
pPce->isValid = 0;
}
} }
pPce->NumEffectiveChannels = pPce->NumChannels; pPce->NumEffectiveChannels = pPce->NumChannels;
for (i = 0; i < pPce->NumLfeChannelElements; i++) { for (i = 0; i < pPce->NumLfeChannelElements; i++) {
pPce->LfeElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); pPce->LfeElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4);
pPce->NumChannels += 1; pPce->NumChannels += 1;
/* Check element instance tag according to ISO/IEC 13818-7:2003(E),
* chapter 8.2.1.1 */
if (checkElementTagSelect[2][tag] == 0) {
checkElementTagSelect[2][tag] = 1;
} else {
pPce->isValid = 0;
}
} }
for (i = 0; i < pPce->NumAssocDataElements; i++) { for (i = 0; i < pPce->NumAssocDataElements; i++) {
@ -336,7 +475,15 @@ void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs,
commentBytes = pPce->CommentFieldBytes; commentBytes = pPce->CommentFieldBytes;
/* Search for height info extension and read it if available */ /* Search for height info extension and read it if available */
err = CProgramConfig_ReadHeightExt(pPce, bs, &commentBytes, alignmentAnchor); if (CProgramConfig_ReadHeightExt(pPce, bs, &commentBytes, alignmentAnchor)) {
pPce->isValid = 0;
}
/* Check order of elements according to ISO / IEC 13818 - 7:2003(E),
* chapter 8.5.1 */
if (CProgramConfig_Check(pPce)) {
pPce->isValid = 0;
}
for (i = 0; i < commentBytes; i++) { for (i = 0; i < commentBytes; i++) {
UCHAR text; UCHAR text;
@ -347,8 +494,6 @@ void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs,
pPce->Comment[i] = text; pPce->Comment[i] = text;
} }
} }
pPce->isValid = (err) ? 0 : 1;
} }
/* /*
@ -1415,7 +1560,7 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
cb->cbSscData, hBs, asc->m_aot, cb->cbSscData, hBs, asc->m_aot,
asc->m_samplingFrequency << esc->m_sbrSamplingRate, asc->m_samplingFrequency << esc->m_sbrSamplingRate,
asc->m_samplesPerFrame << esc->m_sbrSamplingRate, asc->m_samplesPerFrame << esc->m_sbrSamplingRate,
1, /* stereoConfigIndex */ asc->m_channelConfiguration, 1, /* stereoConfigIndex */
-1, /* nTimeSlots: read from bitstream */ -1, /* nTimeSlots: read from bitstream */
eldExtLen, asc->configMode, &asc->SacConfigChanged); eldExtLen, asc->configMode, &asc->SacConfigChanged);
if (ErrorStatus != TRANSPORTDEC_OK) { if (ErrorStatus != TRANSPORTDEC_OK) {
@ -1549,8 +1694,7 @@ static TRANSPORTDEC_ERROR extElementConfig(CSUsacExtElementConfig *extElement,
const AUDIO_OBJECT_TYPE aot) { const AUDIO_OBJECT_TYPE aot) {
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
USAC_EXT_ELEMENT_TYPE usacExtElementType = UINT usacExtElementType = escapedValue(hBs, 4, 8, 16);
(USAC_EXT_ELEMENT_TYPE)escapedValue(hBs, 4, 8, 16);
/* recurve extension elements which are invalid for USAC */ /* recurve extension elements which are invalid for USAC */
if (aot == AOT_USAC) { if (aot == AOT_USAC) {
@ -1567,7 +1711,6 @@ static TRANSPORTDEC_ERROR extElementConfig(CSUsacExtElementConfig *extElement,
} }
} }
extElement->usacExtElementType = usacExtElementType;
int usacExtElementConfigLength = escapedValue(hBs, 4, 8, 16); int usacExtElementConfigLength = escapedValue(hBs, 4, 8, 16);
extElement->usacExtElementConfigLength = (USHORT)usacExtElementConfigLength; extElement->usacExtElementConfigLength = (USHORT)usacExtElementConfigLength;
INT bsAnchor; INT bsAnchor;
@ -1601,8 +1744,10 @@ static TRANSPORTDEC_ERROR extElementConfig(CSUsacExtElementConfig *extElement,
} }
} break; } break;
default: default:
usacExtElementType = ID_EXT_ELE_UNKNOWN;
break; break;
} }
extElement->usacExtElementType = (USAC_EXT_ELEMENT_TYPE)usacExtElementType;
/* Adjust bit stream position. This is required because of byte alignment and /* Adjust bit stream position. This is required because of byte alignment and
* unhandled extensions. */ * unhandled extensions. */
@ -1631,14 +1776,18 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc,
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
int numConfigExtensions; int numConfigExtensions;
CONFIG_EXT_ID usacConfigExtType; UINT usacConfigExtType;
int usacConfigExtLength; int usacConfigExtLength;
int loudnessInfoSetIndex =
-1; /* index of loudnessInfoSet config extension. -1 if not contained. */
int tmp_subStreamIndex = 0;
AUDIO_OBJECT_TYPE tmp_aot = AOT_USAC;
numConfigExtensions = (int)escapedValue(hBs, 2, 4, 8) + 1; numConfigExtensions = (int)escapedValue(hBs, 2, 4, 8) + 1;
for (int confExtIdx = 0; confExtIdx < numConfigExtensions; confExtIdx++) { for (int confExtIdx = 0; confExtIdx < numConfigExtensions; confExtIdx++) {
INT nbits; INT nbits;
int loudnessInfoSetConfigExtensionPosition = FDKgetValidBits(hBs); int loudnessInfoSetConfigExtensionPosition = FDKgetValidBits(hBs);
usacConfigExtType = (CONFIG_EXT_ID)escapedValue(hBs, 4, 8, 16); usacConfigExtType = escapedValue(hBs, 4, 8, 16);
usacConfigExtLength = (int)escapedValue(hBs, 4, 8, 16); usacConfigExtLength = (int)escapedValue(hBs, 4, 8, 16);
/* Start bit position of config extension */ /* Start bit position of config extension */
@ -1662,10 +1811,12 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc,
ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc( ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
cb->cbUniDrcData, hBs, usacConfigExtLength, cb->cbUniDrcData, hBs, usacConfigExtLength,
1, /* loudnessInfoSet */ 1, /* loudnessInfoSet */
0, loudnessInfoSetConfigExtensionPosition, AOT_USAC); tmp_subStreamIndex, loudnessInfoSetConfigExtensionPosition,
tmp_aot);
if (ErrorStatus != TRANSPORTDEC_OK) { if (ErrorStatus != TRANSPORTDEC_OK) {
return ErrorStatus; return ErrorStatus;
} }
loudnessInfoSetIndex = confExtIdx;
} }
} break; } break;
default: default:
@ -1681,6 +1832,17 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc,
FDKpushFor(hBs, usacConfigExtLength); FDKpushFor(hBs, usacConfigExtLength);
} }
if (loudnessInfoSetIndex == -1 && cb->cbUniDrc != NULL) {
/* no loudnessInfoSet contained. Clear the loudnessInfoSet struct by feeding
* an empty config extension */
ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
cb->cbUniDrcData, NULL, 0, 1 /* loudnessInfoSet */, tmp_subStreamIndex,
0, tmp_aot);
if (ErrorStatus != TRANSPORTDEC_OK) {
return ErrorStatus;
}
}
return ErrorStatus; return ErrorStatus;
} }
@ -1697,6 +1859,8 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
int channelElementIdx = int channelElementIdx =
0; /* index for elements which contain audio channels (sce, cpe, lfe) */ 0; /* index for elements which contain audio channels (sce, cpe, lfe) */
SC_CHANNEL_CONFIG sc_chan_config = {0, 0, 0, 0}; SC_CHANNEL_CONFIG sc_chan_config = {0, 0, 0, 0};
int uniDrcElement =
-1; /* index of uniDrc extension element. -1 if not contained. */
numberOfElements = (int)escapedValue(hBs, 4, 8, 16) + 1; numberOfElements = (int)escapedValue(hBs, 4, 8, 16) + 1;
usc->m_usacNumElements = numberOfElements; usc->m_usacNumElements = numberOfElements;
@ -1827,6 +1991,8 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
/* Mps212Config() ISO/IEC FDIS 23003-3 */ /* Mps212Config() ISO/IEC FDIS 23003-3 */
if (cb->cbSsc(cb->cbSscData, hBs, asc->m_aot, if (cb->cbSsc(cb->cbSscData, hBs, asc->m_aot,
asc->m_extensionSamplingFrequency, samplesPerFrame, asc->m_extensionSamplingFrequency, samplesPerFrame,
1, /* only downmix channels (residual channels are
not counted) */
usc->element[i].m_stereoConfigIndex, usc->element[i].m_stereoConfigIndex,
usc->m_coreSbrFrameLengthIndex, usc->m_coreSbrFrameLengthIndex,
0, /* don't know the length */ 0, /* don't know the length */
@ -1870,6 +2036,10 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
case ID_USAC_EXT: case ID_USAC_EXT:
ErrorStatus = extElementConfig(&usc->element[i].extElement, hBs, cb, 0, ErrorStatus = extElementConfig(&usc->element[i].extElement, hBs, cb, 0,
asc->m_samplesPerFrame, 0, asc->m_aot); asc->m_samplesPerFrame, 0, asc->m_aot);
if (usc->element[i].extElement.usacExtElementType ==
ID_EXT_ELE_UNI_DRC) {
uniDrcElement = i;
}
if (ErrorStatus) { if (ErrorStatus) {
return ErrorStatus; return ErrorStatus;
@ -1898,6 +2068,18 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
} }
} }
if (uniDrcElement == -1 && cb->cbUniDrc != NULL) {
/* no uniDrcConfig contained. Clear the uniDrcConfig struct by feeding an
* empty extension element */
int subStreamIndex = 0;
ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
cb->cbUniDrcData, NULL, 0, 0 /* uniDrcConfig */, subStreamIndex, 0,
asc->m_aot);
if (ErrorStatus != TRANSPORTDEC_OK) {
return ErrorStatus;
}
}
return ErrorStatus; return ErrorStatus;
} }
@ -1984,6 +2166,14 @@ static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc,
if (err != TRANSPORTDEC_OK) { if (err != TRANSPORTDEC_OK) {
return err; return err;
} }
} else if (cb->cbUniDrc != NULL) {
/* no loudnessInfoSet contained. Clear the loudnessInfoSet struct by feeding
* an empty config extension */
err = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
cb->cbUniDrcData, NULL, 0, 1 /* loudnessInfoSet */, 0, 0, asc->m_aot);
if (err != TRANSPORTDEC_OK) {
return err;
}
} }
/* sanity check whether number of channels signaled in UsacDecoderConfig() /* sanity check whether number of channels signaled in UsacDecoderConfig()
@ -1996,9 +2186,11 @@ static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc,
/* Copy UsacConfig() to asc->m_sc.m_usacConfig.UsacConfig[] buffer. */ /* Copy UsacConfig() to asc->m_sc.m_usacConfig.UsacConfig[] buffer. */
INT configSize_bits = (INT)FDKgetValidBits(hBs) - nbits; INT configSize_bits = (INT)FDKgetValidBits(hBs) - nbits;
StoreConfigAsBitstream(hBs, configSize_bits, if (StoreConfigAsBitstream(hBs, configSize_bits,
asc->m_sc.m_usacConfig.UsacConfig, asc->m_sc.m_usacConfig.UsacConfig,
TP_USAC_MAX_CONFIG_LEN); TP_USAC_MAX_CONFIG_LEN)) {
return TRANSPORTDEC_PARSE_ERROR;
}
asc->m_sc.m_usacConfig.UsacConfigBits = fAbs(configSize_bits); asc->m_sc.m_usacConfig.UsacConfigBits = fAbs(configSize_bits);
return err; return err;
@ -2219,7 +2411,7 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
case AOT_MPEGS: case AOT_MPEGS:
if (cb->cbSsc != NULL) { if (cb->cbSsc != NULL) {
if (cb->cbSsc(cb->cbSscData, bs, self->m_aot, self->m_samplingFrequency, if (cb->cbSsc(cb->cbSscData, bs, self->m_aot, self->m_samplingFrequency,
self->m_samplesPerFrame, 1, self->m_samplesPerFrame, self->m_channelConfiguration, 1,
-1, /* nTimeSlots: read from bitstream */ -1, /* nTimeSlots: read from bitstream */
0, /* don't know the length */ 0, /* don't know the length */
self->configMode, &self->SacConfigChanged)) { self->configMode, &self->SacConfigChanged)) {
@ -2300,8 +2492,10 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
/* Copy config() to asc->config[] buffer. */ /* Copy config() to asc->config[] buffer. */
if ((ErrorStatus == TRANSPORTDEC_OK) && (self->m_aot == AOT_USAC)) { if ((ErrorStatus == TRANSPORTDEC_OK) && (self->m_aot == AOT_USAC)) {
INT configSize_bits = (INT)FDKgetValidBits(bs) - (INT)ascStartAnchor; INT configSize_bits = (INT)FDKgetValidBits(bs) - (INT)ascStartAnchor;
StoreConfigAsBitstream(bs, configSize_bits, self->config, if (StoreConfigAsBitstream(bs, configSize_bits, self->config,
TP_USAC_MAX_CONFIG_LEN); TP_USAC_MAX_CONFIG_LEN)) {
return TRANSPORTDEC_PARSE_ERROR;
}
self->configBits = fAbs(configSize_bits); self->configBits = fAbs(configSize_bits);
} }
@ -2415,6 +2609,8 @@ static TRANSPORTDEC_ERROR Drm_xHEAACDecoderConfig(
cb->cbSscData, hBs, cb->cbSscData, hBs,
AOT_DRM_USAC, /* syntax differs from MPEG Mps212Config() */ AOT_DRM_USAC, /* syntax differs from MPEG Mps212Config() */
asc->m_extensionSamplingFrequency, samplesPerFrame, asc->m_extensionSamplingFrequency, samplesPerFrame,
1, /* only downmix channels (residual channels are not
counted) */
usc->element[elemIdx].m_stereoConfigIndex, usc->element[elemIdx].m_stereoConfigIndex,
usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */ usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */
asc->configMode, &asc->SacConfigChanged); asc->configMode, &asc->SacConfigChanged);

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -591,6 +591,18 @@ bail:
return (ErrorStatus); return (ErrorStatus);
} }
static int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) {
int len = 0, tmp = 255;
int validBytes = (int)FDKgetValidBits(bs) >> 3;
while (tmp == 255 && validBytes-- > 0) {
tmp = (int)FDKreadBits(bs, 8);
len += tmp;
}
return ((tmp == 255) ? -1 : (len << 3));
}
TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs,
CLatmDemux *pLatmDemux) { CLatmDemux *pLatmDemux) {
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
@ -602,11 +614,17 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs,
FDK_ASSERT(pLatmDemux->m_numLayer[prog] <= LATM_MAX_LAYER); FDK_ASSERT(pLatmDemux->m_numLayer[prog] <= LATM_MAX_LAYER);
for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) { for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
LATM_LAYER_INFO *p_linfo = &pLatmDemux->m_linfo[prog][lay]; LATM_LAYER_INFO *p_linfo = &pLatmDemux->m_linfo[prog][lay];
int auChunkLengthInfo = 0;
switch (p_linfo->m_frameLengthType) { switch (p_linfo->m_frameLengthType) {
case 0: case 0:
p_linfo->m_frameLengthInBits = CLatmDemux_ReadAuChunkLengthInfo(bs); auChunkLengthInfo = CLatmDemux_ReadAuChunkLengthInfo(bs);
if (auChunkLengthInfo >= 0) {
p_linfo->m_frameLengthInBits = (UINT)auChunkLengthInfo;
totalPayloadBits += p_linfo->m_frameLengthInBits; totalPayloadBits += p_linfo->m_frameLengthInBits;
} else {
return TRANSPORTDEC_PARSE_ERROR;
}
break; break;
case 3: case 3:
case 5: case 5:
@ -627,23 +645,6 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs,
return (ErrorStatus); return (ErrorStatus);
} }
int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) {
UCHAR endFlag;
int len = 0;
do {
UCHAR tmp = (UCHAR)FDKreadBits(bs, 8);
endFlag = (tmp < 255);
len += tmp;
} while (endFlag == 0);
len <<= 3; /* convert from bytes to bits */
return len;
}
UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog, UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog,
const UINT layer) { const UINT layer) {
UINT nFrameLenBits = 0; UINT nFrameLenBits = 0;

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -151,8 +151,6 @@ typedef struct {
AudioPreRoll */ AudioPreRoll */
} CLatmDemux; } CLatmDemux;
int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs);
TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs, TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs,
CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt, CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt,
CSTpCallBacks *pTpDecCallbacks, CSTpCallBacks *pTpDecCallbacks,

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -368,7 +368,7 @@ typedef INT (*cbCtrlCFGChange_t)(void *, const CCtrlCFGChange *);
typedef INT (*cbSsc_t)(void *, HANDLE_FDK_BITSTREAM, typedef INT (*cbSsc_t)(void *, HANDLE_FDK_BITSTREAM,
const AUDIO_OBJECT_TYPE coreCodec, const AUDIO_OBJECT_TYPE coreCodec,
const INT samplingRate, const INT frameSize, const INT samplingRate, const INT frameSize,
const INT stereoConfigIndex, const INT numChannels, const INT stereoConfigIndex,
const INT coreSbrFrameLengthIndex, const INT configBytes, const INT coreSbrFrameLengthIndex, const INT configBytes,
const UCHAR configMode, UCHAR *configChanged); const UCHAR configMode, UCHAR *configChanged);

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -795,7 +795,7 @@ static int transportEnc_writeELDSpecificConfig(HANDLE_FDK_BITSTREAM hBs,
const INT eldExtLen = const INT eldExtLen =
(cb->cbSsc(cb->cbSscData, NULL, config->aot, config->extSamplingRate, 0, (cb->cbSsc(cb->cbSscData, NULL, config->aot, config->extSamplingRate, 0,
0, 0, 0, 0, NULL) + 0, 0, 0, 0, 0, NULL) +
7) >> 7) >>
3; 3;
INT cnt = eldExtLen; INT cnt = eldExtLen;
@ -818,7 +818,7 @@ static int transportEnc_writeELDSpecificConfig(HANDLE_FDK_BITSTREAM hBs,
} }
cb->cbSsc(cb->cbSscData, hBs, config->aot, config->extSamplingRate, 0, 0, 0, cb->cbSsc(cb->cbSscData, hBs, config->aot, config->extSamplingRate, 0, 0, 0,
0, 0, NULL); 0, 0, 0, NULL);
} }
if (config->downscaleSamplingRate != 0 && if (config->downscaleSamplingRate != 0 &&

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -322,7 +322,8 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
(FIXP_DBL)SATURATE_LEFT_SHIFT(tmp, scaling, DFRACT_BITS)); (FIXP_DBL)SATURATE_LEFT_SHIFT(tmp, scaling, DFRACT_BITS));
#else #else
samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT( samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT(
tmp + ((FIXP_DBL)0x8000 >> scaling), scaling, DFRACT_BITS)); (tmp >> 1) + ((FIXP_DBL)0x8000 >> (scaling + 1)), scaling + 1,
DFRACT_BITS));
#endif #endif
} }
} }

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -494,13 +494,40 @@ static PCM_DMX_CHANNEL_MODE getChMode4Plain(
return plainChMode; return plainChMode;
} }
static inline UINT getIdxSum(UCHAR numCh) { /** Validates the channel indices of all channels present in the bitstream.
UINT result = 0; * The channel indices have to be consecutive and unique for each audio channel
int i; *type.
for (i = 1; i < numCh; i += 1) { * @param [in] The total number of channels of the given configuration.
result += i; * @param [in] The total number of channels of the current audio channel type of
*the given configuration.
* @param [in] Audio channel type to be examined.
* @param [in] Array holding the corresponding channel types for each channel.
* @param [in] Array holding the corresponding channel type indices for each
*channel.
* @returns Returns 1 on success, returns 0 on error.
**/
static UINT validateIndices(UINT numChannels, UINT numChannelsPlaneAndGrp,
AUDIO_CHANNEL_TYPE aChType,
const AUDIO_CHANNEL_TYPE channelType[],
const UCHAR channelIndices[]) {
for (UINT reqValue = 0; reqValue < numChannelsPlaneAndGrp; reqValue++) {
int found = FALSE;
for (UINT i = 0; i < numChannels; i++) {
if (channelType[i] == aChType) {
if (channelIndices[i] == reqValue) {
if (found == TRUE) {
return 0; /* Found channel index a second time */
} else {
found = TRUE; /* Found channel index */
} }
return result; }
}
}
if (found == FALSE) {
return 0; /* Did not find channel index */
}
}
return 1; /* Successfully validated channel indices */
} }
/** Evaluate a given channel configuration and extract a packed channel mode. In /** Evaluate a given channel configuration and extract a packed channel mode. In
@ -523,7 +550,6 @@ static PCMDMX_ERROR getChannelMode(
UCHAR offsetTable[(8)], /* out */ UCHAR offsetTable[(8)], /* out */
PCM_DMX_CHANNEL_MODE *chMode /* out */ PCM_DMX_CHANNEL_MODE *chMode /* out */
) { ) {
UINT idxSum[(3)][(4)];
UCHAR numCh[(3)][(4)]; UCHAR numCh[(3)][(4)];
UCHAR mapped[(8)]; UCHAR mapped[(8)];
PCM_DMX_SPEAKER_POSITION spkrPos[(8)]; PCM_DMX_SPEAKER_POSITION spkrPos[(8)];
@ -538,7 +564,6 @@ static PCMDMX_ERROR getChannelMode(
FDK_ASSERT(chMode != NULL); FDK_ASSERT(chMode != NULL);
/* For details see ISO/IEC 13818-7:2005(E), 8.5.3 Channel configuration */ /* For details see ISO/IEC 13818-7:2005(E), 8.5.3 Channel configuration */
FDKmemclear(idxSum, (3) * (4) * sizeof(UINT));
FDKmemclear(numCh, (3) * (4) * sizeof(UCHAR)); FDKmemclear(numCh, (3) * (4) * sizeof(UCHAR));
FDKmemclear(mapped, (8) * sizeof(UCHAR)); FDKmemclear(mapped, (8) * sizeof(UCHAR));
FDKmemclear(spkrPos, (8) * sizeof(PCM_DMX_SPEAKER_POSITION)); FDKmemclear(spkrPos, (8) * sizeof(PCM_DMX_SPEAKER_POSITION));
@ -552,19 +577,22 @@ static PCMDMX_ERROR getChannelMode(
(channelType[ch] & 0x0F) - 1, (channelType[ch] & 0x0F) - 1,
0); /* Assign all undefined channels (ACT_NONE) to front channels. */ 0); /* Assign all undefined channels (ACT_NONE) to front channels. */
numCh[channelType[ch] >> 4][chGrp] += 1; numCh[channelType[ch] >> 4][chGrp] += 1;
idxSum[channelType[ch] >> 4][chGrp] += channelIndices[ch];
} }
if (numChannels > TWO_CHANNEL) {
{
int chGrp; int chGrp;
/* Sanity check on the indices */ /* Sanity check on the indices */
for (chGrp = 0; chGrp < (4); chGrp += 1) { for (chGrp = 0; chGrp < (4); chGrp += 1) {
int plane; int plane;
for (plane = 0; plane < (3); plane += 1) { for (plane = 0; plane < (3); plane += 1) {
if (idxSum[plane][chGrp] != getIdxSum(numCh[plane][chGrp])) { if (numCh[plane][chGrp] == 0) continue;
AUDIO_CHANNEL_TYPE aChType =
(AUDIO_CHANNEL_TYPE)((plane << 4) | ((chGrp + 1) & 0xF));
if (!validateIndices(numChannels, numCh[plane][chGrp], aChType,
channelType, channelIndices)) {
unsigned idxCnt = 0; unsigned idxCnt = 0;
for (ch = 0; ch < numChannels; ch += 1) { for (ch = 0; ch < numChannels; ch += 1) {
if (channelType[ch] == if (channelType[ch] == aChType) {
(AUDIO_CHANNEL_TYPE)((plane << 4) | ((chGrp + 1) & 0xF))) {
channelIndices[ch] = idxCnt++; channelIndices[ch] = idxCnt++;
} }
} }

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -316,8 +316,8 @@ SACDEC_ERROR mpegSurroundDecoder_Init(
SACDEC_ERROR mpegSurroundDecoder_Config( SACDEC_ERROR mpegSurroundDecoder_Config(
CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs, CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs,
AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize, AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize,
INT stereoConfigIndex, INT coreSbrFrameLengthIndex, INT configBytes, INT numChannels, INT stereoConfigIndex, INT coreSbrFrameLengthIndex,
const UCHAR configMode, UCHAR *configChanged); INT configBytes, const UCHAR configMode, UCHAR *configChanged);
SACDEC_ERROR SACDEC_ERROR
mpegSurroundDecoder_ConfigureQmfDomain( mpegSurroundDecoder_ConfigureQmfDomain(

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -488,13 +488,18 @@ SACDEC_ERROR SpatialDecParseSpecificConfig(
pSpatialSpecificConfig->freqRes = pSpatialSpecificConfig->freqRes =
(SPATIALDEC_FREQ_RES)freqResTable_LD[bsFreqRes]; (SPATIALDEC_FREQ_RES)freqResTable_LD[bsFreqRes];
pSpatialSpecificConfig->treeConfig = {
(SPATIALDEC_TREE_CONFIG)FDKreadBits(bitstream, 4); UINT treeConfig = FDKreadBits(bitstream, 4);
if (pSpatialSpecificConfig->treeConfig != SPATIALDEC_MODE_RSVD7) { switch (treeConfig) {
case SPATIALDEC_MODE_RSVD7:
pSpatialSpecificConfig->treeConfig = (SPATIALDEC_TREE_CONFIG)treeConfig;
break;
default:
err = MPS_UNSUPPORTED_CONFIG; err = MPS_UNSUPPORTED_CONFIG;
goto bail; goto bail;
} }
}
{ {
pSpatialSpecificConfig->nOttBoxes = pSpatialSpecificConfig->nOttBoxes =

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -1098,6 +1098,28 @@ static void SpatialDecApplyBypass(spatialDec *self, FIXP_DBL **hybInputReal,
} }
} }
/**
* \brief Set internal error and reset error status
*
* \param self spatialDec handle.
* \param bypassMode pointer to bypassMode.
* \param err error status.
*
* \return error status.
*/
static SACDEC_ERROR SpatialDecSetInternalError(spatialDec *self,
int *bypassMode,
SACDEC_ERROR err) {
*bypassMode = 1;
if (self->errInt == MPS_OK) {
/* store internal error before it gets overwritten */
self->errInt = err;
}
return MPS_OK;
}
/******************************************************************************* /*******************************************************************************
Functionname: SpatialDecApplyParameterSets Functionname: SpatialDecApplyParameterSets
******************************************************************************* *******************************************************************************
@ -1118,7 +1140,7 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
const FDK_channelMapDescr *const mapDescr) { const FDK_channelMapDescr *const mapDescr) {
SACDEC_ERROR err = MPS_OK; SACDEC_ERROR err = MPS_OK;
FIXP_SGL alpha; FIXP_SGL alpha = FL2FXCONST_SGL(0.0);
int ts; int ts;
int ch; int ch;
@ -1141,20 +1163,22 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
ts++, ts_io++) { ts++, ts_io++) {
int currSlot = frame->paramSlot[ps]; int currSlot = frame->paramSlot[ps];
err = (currSlot < ts) ? MPS_WRONG_PARAMETERSETS : MPS_OK;
if (err != MPS_OK) {
err = SpatialDecSetInternalError(self, &bypassMode, err);
}
/* /*
* Get new parameter set * Get new parameter set
*/ */
if (ts == prevSlot + 1) { if (ts == prevSlot + 1) {
err = SpatialDecCalculateM1andM2(self, ps, if (bypassMode == 0) {
frame); /* input: ottCLD, ottICC, ... */ err = SpatialDecCalculateM1andM2(
self, ps, frame); /* input: ottCLD, ottICC, ... */
/* output: M1param(Real/Imag), M2(Real/Imag) */ /* output: M1param(Real/Imag), M2(Real/Imag) */
if (err != MPS_OK) { if (err != MPS_OK) {
bypassMode = 1; err = SpatialDecSetInternalError(self, &bypassMode, err);
if (self->errInt == MPS_OK) {
/* store internal error befor it gets overwritten */
self->errInt = err;
} }
err = MPS_OK;
} }
if ((ps == 0) && (self->bOverwriteM1M2prev != 0)) { if ((ps == 0) && (self->bOverwriteM1M2prev != 0)) {
@ -1168,13 +1192,16 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
self->bOverwriteM1M2prev = 0; self->bOverwriteM1M2prev = 0;
} }
if (bypassMode == 0) {
SpatialDecSmoothM1andM2( SpatialDecSmoothM1andM2(
self, frame, self, frame,
ps); /* input: M1param(Real/Imag)(Prev), M2(Real/Imag)(Prev) */ ps); /* input: M1param(Real/Imag)(Prev), M2(Real/Imag)(Prev) */
/* output: M1param(Real/Imag), M2(Real/Imag) */ } /* output: M1param(Real/Imag), M2(Real/Imag) */
} }
if (bypassMode == 0) {
alpha = FX_DBL2FX_SGL(fDivNorm(ts - prevSlot, currSlot - prevSlot)); alpha = FX_DBL2FX_SGL(fDivNorm(ts - prevSlot, currSlot - prevSlot));
}
switch (mode) { switch (mode) {
case INPUTMODE_QMF_SBR: case INPUTMODE_QMF_SBR:
@ -1182,15 +1209,17 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
self->bShareDelayWithSBR = 0; /* We got no hybrid delay */ self->bShareDelayWithSBR = 0; /* We got no hybrid delay */
else else
self->bShareDelayWithSBR = 1; self->bShareDelayWithSBR = 1;
SpatialDecFeedQMF(self, qmfInDataReal, qmfInDataImag, ts_io, bypassMode, SpatialDecFeedQMF(
self, qmfInDataReal, qmfInDataImag, ts_io, bypassMode,
self->qmfInputReal__FDK, self->qmfInputImag__FDK, self->qmfInputReal__FDK, self->qmfInputImag__FDK,
self->numInputChannels); (bypassMode) ? numInputChannels : self->numInputChannels);
break; break;
case INPUTMODE_TIME: case INPUTMODE_TIME:
self->bShareDelayWithSBR = 0; self->bShareDelayWithSBR = 0;
SpatialDecQMFAnalysis(self, inData, ts_io, bypassMode, SpatialDecQMFAnalysis(
self->qmfInputReal__FDK, self->qmfInputImag__FDK, self, inData, ts_io, bypassMode, self->qmfInputReal__FDK,
self->numInputChannels); self->qmfInputImag__FDK,
(bypassMode) ? numInputChannels : self->numInputChannels);
break; break;
default: default:
break; break;
@ -1360,7 +1389,7 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
} /* !self->tempShapeConfig == 1 */ } /* !self->tempShapeConfig == 1 */
} /* !bypassMode */ } /* !bypassMode */
if (self->phaseCoding == 1) { if ((self->phaseCoding == 1) && (bypassMode == 0)) {
/* only if bsPhaseCoding == 1 and bsResidualCoding == 0 */ /* only if bsPhaseCoding == 1 and bsResidualCoding == 0 */
SpatialDecApplyPhase( SpatialDecApplyPhase(

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -700,9 +700,10 @@ bail:
SACDEC_ERROR mpegSurroundDecoder_Config( SACDEC_ERROR mpegSurroundDecoder_Config(
CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs, CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs,
AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize, AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize,
INT stereoConfigIndex, INT coreSbrFrameLengthIndex, INT configBytes, INT numChannels, INT stereoConfigIndex, INT coreSbrFrameLengthIndex,
const UCHAR configMode, UCHAR *configChanged) { INT configBytes, const UCHAR configMode, UCHAR *configChanged) {
SACDEC_ERROR err = MPS_OK; SACDEC_ERROR err = MPS_OK;
INT nInputChannels;
SPATIAL_SPECIFIC_CONFIG spatialSpecificConfig; SPATIAL_SPECIFIC_CONFIG spatialSpecificConfig;
SPATIAL_SPECIFIC_CONFIG *pSsc = SPATIAL_SPECIFIC_CONFIG *pSsc =
&pMpegSurroundDecoder->spatialSpecificConfigBackup; &pMpegSurroundDecoder->spatialSpecificConfigBackup;
@ -716,12 +717,18 @@ SACDEC_ERROR mpegSurroundDecoder_Config(
err = SpatialDecParseMps212Config( err = SpatialDecParseMps212Config(
hBs, &spatialSpecificConfig, samplingRate, coreCodec, hBs, &spatialSpecificConfig, samplingRate, coreCodec,
stereoConfigIndex, coreSbrFrameLengthIndex); stereoConfigIndex, coreSbrFrameLengthIndex);
nInputChannels = spatialSpecificConfig.nInputChannels;
pSsc = &spatialSpecificConfig; pSsc = &spatialSpecificConfig;
} else { } else {
err = SpatialDecParseMps212Config( err = SpatialDecParseMps212Config(
hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup, hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup,
samplingRate, coreCodec, stereoConfigIndex, samplingRate, coreCodec, stereoConfigIndex,
coreSbrFrameLengthIndex); coreSbrFrameLengthIndex);
nInputChannels =
pMpegSurroundDecoder->spatialSpecificConfigBackup.nInputChannels;
}
if ((err == MPS_OK) && (numChannels != nInputChannels)) {
err = MPS_PARSE_ERROR;
} }
break; break;
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
@ -731,11 +738,19 @@ SACDEC_ERROR mpegSurroundDecoder_Config(
* into temporarily allocated structure */ * into temporarily allocated structure */
err = SpatialDecParseSpecificConfig(hBs, &spatialSpecificConfig, err = SpatialDecParseSpecificConfig(hBs, &spatialSpecificConfig,
configBytes, coreCodec); configBytes, coreCodec);
nInputChannels = spatialSpecificConfig.nInputChannels;
pSsc = &spatialSpecificConfig; pSsc = &spatialSpecificConfig;
} else { } else {
err = SpatialDecParseSpecificConfig( err = SpatialDecParseSpecificConfig(
hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup, hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup,
configBytes, coreCodec); configBytes, coreCodec);
nInputChannels =
pMpegSurroundDecoder->spatialSpecificConfigBackup.nInputChannels;
}
/* check number of channels for channel_configuration > 0 */
if ((err == MPS_OK) && (numChannels > 0) &&
(numChannels != nInputChannels)) {
err = MPS_PARSE_ERROR;
} }
break; break;
default: default:

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -517,12 +517,11 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
maxVal = fAbs(iReal0) | fAbs(iImag0); maxVal = fAbs(iReal0) | fAbs(iImag0);
maxVal |= fAbs(iReal1); maxVal |= fAbs(iReal1);
s = fMax(CntLeadingZeros(maxVal) - 1, 0); s = fMin(CntLeadingZeros(maxVal) - 2, scale_param_m2);
s = fMin(s, scale_param_m2);
mReal0 = iReal0 << s; mReal0 = scaleValue(iReal0, s);
mImag0 = iImag0 << s; mImag0 = scaleValue(iImag0, s);
mReal1 = iReal1 << s; mReal1 = scaleValue(iReal1, s);
s = scale_param_m2 - s; s = scale_param_m2 - s;
@ -562,12 +561,11 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
maxVal = fAbs(iReal0) | fAbs(iImag0); maxVal = fAbs(iReal0) | fAbs(iImag0);
maxVal |= fAbs(iReal1); maxVal |= fAbs(iReal1);
s = fMax(CntLeadingZeros(maxVal) - 1, 0); s = fMin(CntLeadingZeros(maxVal) - 2, scale_param_m2);
s = fMin(s, scale_param_m2);
mReal0 = FX_DBL2FX_SGL(iReal0 << s); mReal0 = FX_DBL2FX_SGL(scaleValue(iReal0, s));
mImag0 = FX_DBL2FX_SGL(iImag0 << s); mImag0 = FX_DBL2FX_SGL(scaleValue(iImag0, s));
mReal1 = FX_DBL2FX_SGL(iReal1 << s); mReal1 = FX_DBL2FX_SGL(scaleValue(iReal1, s));
s = scale_param_m2 - s; s = scale_param_m2 - s;

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -241,29 +241,56 @@ static inline void combineDryWet(FIXP_DBL *RESTRICT pReal,
} }
} }
static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry, static inline void slotAmp(
FIXP_DBL *RESTRICT slotAmp_wet, FIXP_DBL *RESTRICT slotAmp_dry, INT *RESTRICT slotAmp_dry_e,
FIXP_DBL *RESTRICT pHybOutputRealDry, FIXP_DBL *RESTRICT slotAmp_wet, INT *RESTRICT slotAmp_wet_e,
FIXP_DBL *RESTRICT pHybOutputImagDry, FIXP_DBL *RESTRICT pHybOutputRealDry, FIXP_DBL *RESTRICT pHybOutputImagDry,
FIXP_DBL *RESTRICT pHybOutputRealWet, FIXP_DBL *RESTRICT pHybOutputRealWet, FIXP_DBL *RESTRICT pHybOutputImagWet,
FIXP_DBL *RESTRICT pHybOutputImagWet, INT cplxBands, INT cplxBands, INT hybBands) {
INT hybBands) { INT qs, s1, s2, headroom_dry, headroom_wet;
INT qs;
FIXP_DBL dry, wet; FIXP_DBL dry, wet;
/* headroom can be reduced by 1 bit due to use of fPow2Div2 */
s1 = DFRACT_BITS - 1 - CntLeadingZeros(hybBands + cplxBands);
headroom_dry = fMin(getScalefactor(pHybOutputRealDry, hybBands),
getScalefactor(pHybOutputImagDry, cplxBands));
headroom_wet = fMin(getScalefactor(pHybOutputRealWet, hybBands),
getScalefactor(pHybOutputImagWet, cplxBands));
dry = wet = FL2FXCONST_DBL(0.0f); dry = wet = FL2FXCONST_DBL(0.0f);
for (qs = 0; qs < cplxBands; qs++) { for (qs = 0; qs < cplxBands; qs++) {
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)) + /* sum up dry part */
fPow2Div2(pHybOutputImagDry[qs] << (1))); dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)) + dry += (fPow2Div2(pHybOutputImagDry[qs] << headroom_dry) >> s1);
fPow2Div2(pHybOutputImagWet[qs] << (1))); /* sum up wet part */
wet += (fPow2Div2(pHybOutputRealWet[qs] << headroom_wet) >> s1);
wet += (fPow2Div2(pHybOutputImagWet[qs] << headroom_wet) >> s1);
} }
for (; qs < hybBands; qs++) { for (; qs < hybBands; qs++) {
dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1))); dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1))); wet += (fPow2Div2(pHybOutputRealWet[qs] << headroom_wet) >> s1);
}
/* consider fPow2Div2() */
s1 += 1;
/* normalize dry part, ensure that exponent is even */
s2 = fixMax(0, CntLeadingZeros(dry) - 1);
*slotAmp_dry = dry << s2;
*slotAmp_dry_e = s1 - s2 - 2 * headroom_dry;
if (*slotAmp_dry_e & 1) {
*slotAmp_dry = *slotAmp_dry >> 1;
*slotAmp_dry_e += 1;
}
/* normalize wet part, ensure that exponent is even */
s2 = fixMax(0, CntLeadingZeros(wet) - 1);
*slotAmp_wet = wet << s2;
*slotAmp_wet_e = s1 - s2 - 2 * headroom_wet;
if (*slotAmp_wet_e & 1) {
*slotAmp_wet = *slotAmp_wet >> 1;
*slotAmp_wet_e += 1;
} }
*slotAmp_dry = dry >> (2 * (1));
*slotAmp_wet = wet >> (2 * (1));
} }
#if defined(__aarch64__) #if defined(__aarch64__)
@ -533,6 +560,7 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
INT ts) { INT ts) {
INT ch, scale; INT ch, scale;
INT dryFacSF, slotAmpSF; INT dryFacSF, slotAmpSF;
INT slotAmp_dry_e, slotAmp_wet_e;
FIXP_DBL tmp, dryFac, envShape; FIXP_DBL tmp, dryFac, envShape;
FIXP_DBL slotAmp_dry, slotAmp_wet, slotAmp_ratio; FIXP_DBL slotAmp_dry, slotAmp_wet, slotAmp_ratio;
FIXP_DBL envDry[MAX_OUTPUT_CHANNELS], envDmx[2]; FIXP_DBL envDry[MAX_OUTPUT_CHANNELS], envDmx[2];
@ -594,22 +622,25 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
dryFacSF = SF_SHAPE + 2 * dryFacSF; dryFacSF = SF_SHAPE + 2 * dryFacSF;
} }
slotAmp_dry_e = slotAmp_wet_e = 0;
/* calculate slotAmp_dry and slotAmp_wet */ /* calculate slotAmp_dry and slotAmp_wet */
slotAmp(&slotAmp_dry, &slotAmp_wet, &self->hybOutputRealDry__FDK[ch][6], slotAmp(&slotAmp_dry, &slotAmp_dry_e, &slotAmp_wet, &slotAmp_wet_e,
&self->hybOutputRealDry__FDK[ch][6],
&self->hybOutputImagDry__FDK[ch][6], &self->hybOutputImagDry__FDK[ch][6],
&self->hybOutputRealWet__FDK[ch][6], &self->hybOutputRealWet__FDK[ch][6],
&self->hybOutputImagWet__FDK[ch][6], cplxBands, hybBands); &self->hybOutputImagWet__FDK[ch][6], cplxBands, hybBands);
/* exponents must be even due to subsequent square root calculation */
FDK_ASSERT(((slotAmp_dry_e & 1) == 0) && ((slotAmp_wet_e & 1) == 0));
/* slotAmp_ratio will be scaled by slotAmpSF bits */ /* slotAmp_ratio will be scaled by slotAmpSF bits */
if (slotAmp_dry != FL2FXCONST_DBL(0.0f)) { if (slotAmp_dry != FL2FXCONST_DBL(0.0f)) {
sc = fixMax(0, CntLeadingZeros(slotAmp_wet) - 1); slotAmp_wet = sqrtFixp(slotAmp_wet);
sc = sc - (sc & 1);
slotAmp_wet = sqrtFixp(slotAmp_wet << sc);
slotAmp_dry = invSqrtNorm2(slotAmp_dry, &slotAmpSF); slotAmp_dry = invSqrtNorm2(slotAmp_dry, &slotAmpSF);
slotAmp_ratio = fMult(slotAmp_wet, slotAmp_dry); slotAmp_ratio = fMult(slotAmp_wet, slotAmp_dry);
slotAmpSF = slotAmpSF - (sc >> 1); slotAmpSF = slotAmpSF + (slotAmp_wet_e >> 1) - (slotAmp_dry_e >> 1);
} }
/* calculate common scale factor */ /* calculate common scale factor */

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -229,15 +229,13 @@ inline void combineSignalCplxScale1(FIXP_DBL *hybOutputRealDry,
int n; int n;
FIXP_DBL scaleY; FIXP_DBL scaleY;
for (n = bands - 1; n >= 0; n--) { for (n = bands - 1; n >= 0; n--) {
scaleY = fMultDiv2(scaleX, *pBP); scaleY = fMult(scaleX, *pBP);
*hybOutputRealDry = SATURATE_LEFT_SHIFT( *hybOutputRealDry = SATURATE_LEFT_SHIFT(
(*hybOutputRealDry >> 1) + (*hybOutputRealDry >> SF_SCALE) + fMult(*hybOutputRealWet, scaleY),
(fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 1)), SF_SCALE, DFRACT_BITS);
1, DFRACT_BITS);
*hybOutputImagDry = SATURATE_LEFT_SHIFT( *hybOutputImagDry = SATURATE_LEFT_SHIFT(
(*hybOutputImagDry >> 1) + (*hybOutputImagDry >> SF_SCALE) + fMult(*hybOutputImagWet, scaleY),
(fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 1)), SF_SCALE, DFRACT_BITS);
1, DFRACT_BITS);
hybOutputRealDry++, hybOutputRealWet++; hybOutputRealDry++, hybOutputRealWet++;
hybOutputImagDry++, hybOutputImagWet++; hybOutputImagDry++, hybOutputImagWet++;
pBP++; pBP++;
@ -252,12 +250,12 @@ inline void combineSignalCplxScale2(FIXP_DBL *hybOutputRealDry,
int n; int n;
for (n = bands - 1; n >= 0; n--) { for (n = bands - 1; n >= 0; n--) {
*hybOutputRealDry = *hybOutputRealDry = SATURATE_LEFT_SHIFT(
*hybOutputRealDry + (*hybOutputRealDry >> SF_SCALE) + fMult(*hybOutputRealWet, scaleX),
(fMultDiv2(*hybOutputRealWet, scaleX) << (SF_SCALE + 1)); SF_SCALE, DFRACT_BITS);
*hybOutputImagDry = *hybOutputImagDry = SATURATE_LEFT_SHIFT(
*hybOutputImagDry + (*hybOutputImagDry >> SF_SCALE) + fMult(*hybOutputImagWet, scaleX),
(fMultDiv2(*hybOutputImagWet, scaleX) << (SF_SCALE + 1)); SF_SCALE, DFRACT_BITS);
hybOutputRealDry++, hybOutputRealWet++; hybOutputRealDry++, hybOutputRealWet++;
hybOutputImagDry++, hybOutputImagWet++; hybOutputImagDry++, hybOutputImagWet++;
} }
@ -369,15 +367,15 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
hStpDec->update_old_ener = 1; hStpDec->update_old_ener = 1;
for (ch = 0; ch < self->numInputChannels; ch++) { for (ch = 0; ch < self->numInputChannels; ch++) {
hStpDec->oldDryEnerLD64[ch] = hStpDec->oldDryEnerLD64[ch] =
CalcLdData(hStpDec->runDryEner[ch] + ABS_THR__FDK); CalcLdData(fAddSaturate(hStpDec->runDryEner[ch], ABS_THR__FDK));
} }
for (ch = 0; ch < self->numOutputChannels; ch++) { for (ch = 0; ch < self->numOutputChannels; ch++) {
if (self->treeConfig == TREE_212) if (self->treeConfig == TREE_212)
hStpDec->oldWetEnerLD64[ch] = hStpDec->oldWetEnerLD64[ch] =
CalcLdData(hStpDec->runWetEner[ch] + ABS_THR__FDK); CalcLdData(fAddSaturate(hStpDec->runWetEner[ch], ABS_THR__FDK));
else else
hStpDec->oldWetEnerLD64[ch] = hStpDec->oldWetEnerLD64[ch] =
CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK); CalcLdData(fAddSaturate(hStpDec->runWetEner[ch], ABS_THR2__FDK));
} }
} else { } else {
hStpDec->update_old_ener++; hStpDec->update_old_ener++;

View File

@ -1,159 +0,0 @@
/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
scheme for digital audio. This FDK AAC Codec software is intended to be used on
a wide variety of Android devices.
AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
general perceptual audio codecs. AAC-ELD is considered the best-performing
full-bandwidth communications codec by independent studies and is widely
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
specifications.
Patent licenses for necessary patent claims for the FDK AAC Codec (including
those of Fraunhofer) may be obtained through Via Licensing
(www.vialicensing.com) or through the respective patent owners individually for
the purpose of encoding or decoding bit streams in products that are compliant
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
Android devices already license these patent claims through Via Licensing or
directly from the patent owners, and therefore FDK AAC Codec software may
already be covered under those patent licenses when it is used for those
licensed purposes only.
Commercially-licensed AAC software libraries, including floating-point versions
with enhanced sound quality, are also available from Fraunhofer. Users are
encouraged to check the Fraunhofer website for additional applications
information and documentation.
2. COPYRIGHT LICENSE
Redistribution and use in source and binary forms, with or without modification,
are permitted without payment of copyright license fees provided that you
satisfy the following conditions:
You must retain the complete text of this software license in redistributions of
the FDK AAC Codec or your modifications thereto in source code form.
You must retain the complete text of this software license in the documentation
and/or other materials provided with redistributions of the FDK AAC Codec or
your modifications thereto in binary form. You must make available free of
charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
The name of Fraunhofer may not be used to endorse or promote products derived
from this library without prior written permission.
You may not charge copyright license fees for anyone to use, copy or distribute
the FDK AAC Codec software or your modifications thereto.
Your modified versions of the FDK AAC Codec must carry prominent notices stating
that you changed the software and the date of any change. For modified versions
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
AAC Codec Library for Android."
3. NO PATENT LICENSE
NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
Fraunhofer provides no warranty of patent non-infringement with respect to this
software.
You may use this FDK AAC Codec software or modifications thereto only for
purposes that are authorized by appropriate patent licenses.
4. DISCLAIMER
This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
including but not limited to the implied warranties of merchantability and
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
or consequential damages, including but not limited to procurement of substitute
goods or services; loss of use, data, or profits, or business interruption,
however caused and on any theory of liability, whether in contract, strict
liability, or tort (including negligence), arising in any way out of the use of
this software, even if advised of the possibility of such damage.
5. CONTACT INFORMATION
Fraunhofer Institute for Integrated Circuits IIS
Attention: Audio and Multimedia Departments - FDK AAC LL
Am Wolfsmantel 33
91058 Erlangen, Germany
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------- */
/**************************** SBR decoder library ******************************
Author(s): Arthur Tritthart
Description: (ARM optimised) LPP transposer subroutines
*******************************************************************************/
#if defined(__arm__)
#define FUNCTION_LPPTRANSPOSER_func1
#ifdef FUNCTION_LPPTRANSPOSER_func1
/* Note: This code requires only 43 cycles per iteration instead of 61 on
* ARM926EJ-S */
static void lppTransposer_func1(FIXP_DBL *lowBandReal, FIXP_DBL *lowBandImag,
FIXP_DBL **qmfBufferReal,
FIXP_DBL **qmfBufferImag, int loops, int hiBand,
int dynamicScale, int descale, FIXP_SGL a0r,
FIXP_SGL a0i, FIXP_SGL a1r, FIXP_SGL a1i,
const int fPreWhitening,
FIXP_DBL preWhiteningGain,
int preWhiteningGains_sf) {
FIXP_DBL real1, real2, imag1, imag2, accu1, accu2;
real2 = lowBandReal[-2];
real1 = lowBandReal[-1];
imag2 = lowBandImag[-2];
imag1 = lowBandImag[-1];
for (int i = 0; i < loops; i++) {
accu1 = fMultDiv2(a0r, real1);
accu2 = fMultDiv2(a0i, imag1);
accu1 = fMultAddDiv2(accu1, a1r, real2);
accu2 = fMultAddDiv2(accu2, a1i, imag2);
real2 = fMultDiv2(a1i, real2);
accu1 = accu1 - accu2;
accu1 = accu1 >> dynamicScale;
accu2 = fMultAddDiv2(real2, a1r, imag2);
real2 = real1;
imag2 = imag1;
accu2 = fMultAddDiv2(accu2, a0i, real1);
real1 = lowBandReal[i];
accu2 = fMultAddDiv2(accu2, a0r, imag1);
imag1 = lowBandImag[i];
accu2 = accu2 >> dynamicScale;
accu1 <<= 1;
accu2 <<= 1;
accu1 += (real1 >> descale);
accu2 += (imag1 >> descale);
if (fPreWhitening) {
accu1 = scaleValueSaturate(fMultDiv2(accu1, preWhiteningGain),
preWhiteningGains_sf);
accu2 = scaleValueSaturate(fMultDiv2(accu2, preWhiteningGain),
preWhiteningGains_sf);
}
qmfBufferReal[i][hiBand] = accu1;
qmfBufferImag[i][hiBand] = accu2;
}
}
#endif /* #ifdef FUNCTION_LPPTRANSPOSER_func1 */
#endif /* __arm__ */

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -664,7 +664,7 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
gain_sf[i] = mult_sf - total_power_low_sf + sf2; gain_sf[i] = mult_sf - total_power_low_sf + sf2;
gain[i] = sqrtFixp_lookup(gain[i], &gain_sf[i]); gain[i] = sqrtFixp_lookup(gain[i], &gain_sf[i]);
if (gain_sf[i] < 0) { if (gain_sf[i] < 0) {
gain[i] >>= -gain_sf[i]; gain[i] >>= fMin(DFRACT_BITS - 1, -gain_sf[i]);
gain_sf[i] = 0; gain_sf[i] = 0;
} }
} else { } else {
@ -683,11 +683,6 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
/* gain[i] = g_inter[i] */ /* gain[i] = g_inter[i] */
for (i = 0; i < nbSubsample; ++i) { for (i = 0; i < nbSubsample; ++i) {
if (gain_sf[i] < 0) {
gain[i] >>= -gain_sf[i];
gain_sf[i] = 0;
}
/* calculate: gain[i] = 1.0f + gamma * (gain[i] - 1.0f); */ /* calculate: gain[i] = 1.0f + gamma * (gain[i] - 1.0f); */
FIXP_DBL one = (FIXP_DBL)MAXVAL_DBL >> FIXP_DBL one = (FIXP_DBL)MAXVAL_DBL >>
gain_sf[i]; /* to substract this from gain[i] */ gain_sf[i]; /* to substract this from gain[i] */
@ -755,23 +750,15 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
int gain_adj_sf = gain_adj_2_sf; int gain_adj_sf = gain_adj_2_sf;
for (i = 0; i < nbSubsample; ++i) { for (i = 0; i < nbSubsample; ++i) {
gain[i] = fMult(gain[i], gain_adj); int gain_e = fMax(
gain_sf[i] += gain_adj_sf; fMin(gain_sf[i] + gain_adj_sf - INTER_TES_SF_CHANGE, DFRACT_BITS - 1),
-(DFRACT_BITS - 1));
/* limit gain */ FIXP_DBL gain_final = fMult(gain[i], gain_adj);
if (gain_sf[i] > INTER_TES_SF_CHANGE) { gain_final = scaleValueSaturate(gain_final, gain_e);
gain[i] = (FIXP_DBL)MAXVAL_DBL;
gain_sf[i] = INTER_TES_SF_CHANGE;
}
}
for (i = 0; i < nbSubsample; ++i) {
/* equalize gain[]'s scale factors */
gain[i] >>= INTER_TES_SF_CHANGE - gain_sf[i];
for (j = lowSubband; j < highSubband; j++) { for (j = lowSubband; j < highSubband; j++) {
qmfReal[startPos + i][j] = fMult(qmfReal[startPos + i][j], gain[i]); qmfReal[startPos + i][j] = fMult(qmfReal[startPos + i][j], gain_final);
qmfImag[startPos + i][j] = fMult(qmfImag[startPos + i][j], gain[i]); qmfImag[startPos + i][j] = fMult(qmfImag[startPos + i][j], gain_final);
} }
} }
} else { /* gamma_idx == 0 */ } else { /* gamma_idx == 0 */
@ -1398,6 +1385,17 @@ void calculateSbrEnvelope(
*/ */
noise_e = (start_pos < no_cols) ? adj_e : final_e; noise_e = (start_pos < no_cols) ? adj_e : final_e;
if (start_pos >= no_cols) {
int diff = h_sbr_cal_env->filtBufferNoise_e - noise_e;
if (diff > 0) {
int s = getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands);
if (diff > s) {
final_e += diff - s;
noise_e = final_e;
}
}
}
/* /*
Convert energies to amplitude levels Convert energies to amplitude levels
*/ */
@ -2741,6 +2739,9 @@ static void adjustTimeSlotHQ_GainAndNoise(
fMult(direct_ratio, noiseLevel[k]); fMult(direct_ratio, noiseLevel[k]);
} }
smoothedNoise = fMax(fMin(smoothedNoise, (FIXP_DBL)(MAXVAL_DBL / 2)),
(FIXP_DBL)(MINVAL_DBL / 2));
/* /*
The next 2 multiplications constitute the actual envelope adjustment The next 2 multiplications constitute the actual envelope adjustment
of the signal and should be carried out with full accuracy of the signal and should be carried out with full accuracy
@ -2930,6 +2931,9 @@ static void adjustTimeSlotHQ(
fMult(direct_ratio, noiseLevel[k]); fMult(direct_ratio, noiseLevel[k]);
} }
smoothedNoise = fMax(fMin(smoothedNoise, (FIXP_DBL)(MAXVAL_DBL / 2)),
(FIXP_DBL)(MINVAL_DBL / 2));
/* /*
The next 2 multiplications constitute the actual envelope adjustment The next 2 multiplications constitute the actual envelope adjustment
of the signal and should be carried out with full accuracy of the signal and should be carried out with full accuracy

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -1400,42 +1400,27 @@ void QmfTransposerApply(HANDLE_HBE_TRANSPOSER hQmfTransposer,
if (shift_ov != 0) { if (shift_ov != 0) {
for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) { for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) {
for (band = 0; band < QMF_SYNTH_CHANNELS; band++) { scaleValuesSaturate(&hQmfTransposer->qmfHBEBufReal_F[i][0],
if (shift_ov >= 0) { QMF_SYNTH_CHANNELS, shift_ov);
hQmfTransposer->qmfHBEBufReal_F[i][band] <<= shift_ov; scaleValuesSaturate(&hQmfTransposer->qmfHBEBufImag_F[i][0],
hQmfTransposer->qmfHBEBufImag_F[i][band] <<= shift_ov; QMF_SYNTH_CHANNELS, shift_ov);
} else {
hQmfTransposer->qmfHBEBufReal_F[i][band] >>= (-shift_ov);
hQmfTransposer->qmfHBEBufImag_F[i][band] >>= (-shift_ov);
}
}
}
} }
if ((keepStatesSyncedMode == KEEP_STATES_SYNCED_OFF) && shift_ov != 0) { if (keepStatesSyncedMode == KEEP_STATES_SYNCED_OFF) {
int nBands =
fMax(0, hQmfTransposer->stopBand - hQmfTransposer->startBand);
for (i = timeStep * firstSlotOffsset; i < ov_len; i++) { for (i = timeStep * firstSlotOffsset; i < ov_len; i++) {
for (band = hQmfTransposer->startBand; band < hQmfTransposer->stopBand; scaleValuesSaturate(&ppQmfBufferOutReal_F[i][hQmfTransposer->startBand],
band++) { nBands, shift_ov);
if (shift_ov >= 0) { scaleValuesSaturate(&ppQmfBufferOutImag_F[i][hQmfTransposer->startBand],
ppQmfBufferOutReal_F[i][band] <<= shift_ov; nBands, shift_ov);
ppQmfBufferOutImag_F[i][band] <<= shift_ov;
} else {
ppQmfBufferOutReal_F[i][band] >>= (-shift_ov);
ppQmfBufferOutImag_F[i][band] >>= (-shift_ov);
}
}
} }
/* shift lpc filterstates */ /* shift lpc filterstates */
for (i = 0; i < timeStep * firstSlotOffsset + LPC_ORDER; i++) { for (i = 0; i < timeStep * firstSlotOffsset + LPC_ORDER; i++) {
for (band = 0; band < (64); band++) { scaleValuesSaturate(&lpcFilterStatesReal[i][0], (64), shift_ov);
if (shift_ov >= 0) { scaleValuesSaturate(&lpcFilterStatesImag[i][0], (64), shift_ov);
lpcFilterStatesReal[i][band] <<= shift_ov;
lpcFilterStatesImag[i][band] <<= shift_ov;
} else {
lpcFilterStatesReal[i][band] >>= (-shift_ov);
lpcFilterStatesImag[i][band] >>= (-shift_ov);
}
} }
} }
} }

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -132,10 +132,6 @@ amm-info@iis.fraunhofer.de
#include "HFgen_preFlat.h" #include "HFgen_preFlat.h"
#if defined(__arm__)
#include "arm/lpp_tran_arm.cpp"
#endif
#define LPC_SCALE_FACTOR 2 #define LPC_SCALE_FACTOR 2
/*! /*!
@ -220,19 +216,21 @@ static inline void calc_qmfBufferReal(FIXP_DBL **qmfBufferReal,
const FIXP_DBL *const lowBandReal, const FIXP_DBL *const lowBandReal,
const int startSample, const int startSample,
const int stopSample, const UCHAR hiBand, const int stopSample, const UCHAR hiBand,
const int dynamicScale, const int descale, const int dynamicScale,
const FIXP_SGL a0r, const FIXP_SGL a1r) { const FIXP_SGL a0r, const FIXP_SGL a1r) {
FIXP_DBL accu1, accu2; const int dynscale = fixMax(0, dynamicScale - 1) + 1;
int i; const int rescale = -fixMin(0, dynamicScale - 1) + 1;
const int descale =
fixMin(DFRACT_BITS - 1, LPC_SCALE_FACTOR + dynamicScale + rescale);
for (i = 0; i < stopSample - startSample; i++) { for (int i = 0; i < stopSample - startSample; i++) {
accu1 = fMultDiv2(a1r, lowBandReal[i]); FIXP_DBL accu;
accu1 = (fMultDiv2(a0r, lowBandReal[i + 1]) + accu1);
accu1 = accu1 >> dynamicScale;
accu1 <<= 1; accu = fMultDiv2(a1r, lowBandReal[i]) + fMultDiv2(a0r, lowBandReal[i + 1]);
accu2 = (lowBandReal[i + 2] >> descale); accu = (lowBandReal[i + 2] >> descale) + (accu >> dynscale);
qmfBufferReal[i + startSample][hiBand] = accu1 + accu2;
qmfBufferReal[i + startSample][hiBand] =
SATURATE_LEFT_SHIFT(accu, rescale, DFRACT_BITS);
} }
} }
@ -529,7 +527,7 @@ void lppTransposer(
if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) { if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) {
resetLPCCoeffs = 1; resetLPCCoeffs = 1;
} else { } else {
alphar[1] = FX_DBL2FX_SGL(scaleValue(result, scale)); alphar[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
alphar[1] = -alphar[1]; alphar[1] = -alphar[1];
} }
@ -557,7 +555,7 @@ void lppTransposer(
scale)) { scale)) {
resetLPCCoeffs = 1; resetLPCCoeffs = 1;
} else { } else {
alphai[1] = FX_DBL2FX_SGL(scaleValue(result, scale)); alphai[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
alphai[1] = -alphai[1]; alphai[1] = -alphai[1];
} }
@ -596,7 +594,7 @@ void lppTransposer(
} else { } else {
INT scale; INT scale;
FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
alphar[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1)); alphar[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
alphar[0] = -alphar[0]; alphar[0] = -alphar[0];
@ -616,7 +614,7 @@ void lppTransposer(
} else { } else {
INT scale; INT scale;
FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
alphai[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1)); alphai[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
alphai[0] = -alphai[0]; alphai[0] = -alphai[0];
} }
@ -659,7 +657,7 @@ void lppTransposer(
INT scale; INT scale;
FIXP_DBL result = FIXP_DBL result =
fDivNorm(fixp_abs(ac.r01r), fixp_abs(ac.r11r), &scale); fDivNorm(fixp_abs(ac.r01r), fixp_abs(ac.r11r), &scale);
k1 = scaleValue(result, scale); k1 = scaleValueSaturate(result, scale);
if (!((ac.r01r < FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))) { if (!((ac.r01r < FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))) {
k1 = -k1; k1 = -k1;
@ -771,52 +769,50 @@ void lppTransposer(
} else { /* bw <= 0 */ } else { /* bw <= 0 */
if (!useLP) { if (!useLP) {
int descale = const int dynscale = fixMax(0, dynamicScale - 2) + 1;
fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)); const int rescale = -fixMin(0, dynamicScale - 2) + 1;
#ifdef FUNCTION_LPPTRANSPOSER_func1 const int descale = fixMin(DFRACT_BITS - 1,
lppTransposer_func1( LPC_SCALE_FACTOR + dynamicScale + rescale);
lowBandReal + LPC_ORDER + startSample,
lowBandImag + LPC_ORDER + startSample,
qmfBufferReal + startSample, qmfBufferImag + startSample,
stopSample - startSample, (int)hiBand, dynamicScale, descale, a0r,
a0i, a1r, a1i, fPreWhitening, preWhiteningGains[loBand],
preWhiteningGains_exp[loBand] + 1);
#else
for (i = startSample; i < stopSample; i++) { for (i = startSample; i < stopSample; i++) {
FIXP_DBL accu1, accu2; FIXP_DBL accu1, accu2;
accu1 = (fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) - accu1 = ((fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) -
fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1]) + fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1])) >>
fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) - 1) +
((fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) -
fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >> fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >>
dynamicScale; 1);
accu2 = (fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) + accu2 = ((fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) +
fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1]) + fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1])) >>
fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) + 1) +
((fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) +
fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >> fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >>
dynamicScale; 1);
accu1 = (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << 1); accu1 =
accu2 = (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << 1); (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 >> dynscale);
accu2 =
(lowBandImag[LPC_ORDER + i] >> descale) + (accu2 >> dynscale);
if (fPreWhitening) { if (fPreWhitening) {
accu1 = scaleValueSaturate( qmfBufferReal[i][hiBand] = scaleValueSaturate(
fMultDiv2(accu1, preWhiteningGains[loBand]), fMultDiv2(accu1, preWhiteningGains[loBand]),
preWhiteningGains_exp[loBand] + 1); preWhiteningGains_exp[loBand] + 1 + rescale);
accu2 = scaleValueSaturate( qmfBufferImag[i][hiBand] = scaleValueSaturate(
fMultDiv2(accu2, preWhiteningGains[loBand]), fMultDiv2(accu2, preWhiteningGains[loBand]),
preWhiteningGains_exp[loBand] + 1); preWhiteningGains_exp[loBand] + 1 + rescale);
} else {
qmfBufferReal[i][hiBand] =
SATURATE_LEFT_SHIFT(accu1, rescale, DFRACT_BITS);
qmfBufferImag[i][hiBand] =
SATURATE_LEFT_SHIFT(accu2, rescale, DFRACT_BITS);
} }
qmfBufferReal[i][hiBand] = accu1;
qmfBufferImag[i][hiBand] = accu2;
} }
#endif
} else { } else {
FDK_ASSERT(dynamicScale >= 0); FDK_ASSERT(dynamicScale >= 0);
calc_qmfBufferReal( calc_qmfBufferReal(
qmfBufferReal, &(lowBandReal[LPC_ORDER + startSample - 2]), qmfBufferReal, &(lowBandReal[LPC_ORDER + startSample - 2]),
startSample, stopSample, hiBand, dynamicScale, startSample, stopSample, hiBand, dynamicScale, a0r, a1r);
fMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)), a0r,
a1r);
} }
} /* bw <= 0 */ } /* bw <= 0 */
@ -1066,7 +1062,7 @@ void lppTransposerHBE(
if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) { if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) {
resetLPCCoeffs = 1; resetLPCCoeffs = 1;
} else { } else {
alphar[1] = FX_DBL2FX_SGL(scaleValue(result, scale)); alphar[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
alphar[1] = -alphar[1]; alphar[1] = -alphar[1];
} }
@ -1092,7 +1088,7 @@ void lppTransposerHBE(
(result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >> scale)) { (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >> scale)) {
resetLPCCoeffs = 1; resetLPCCoeffs = 1;
} else { } else {
alphai[1] = FX_DBL2FX_SGL(scaleValue(result, scale)); alphai[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale));
if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) {
alphai[1] = -alphai[1]; alphai[1] = -alphai[1];
} }
@ -1121,7 +1117,7 @@ void lppTransposerHBE(
} else { } else {
INT scale; INT scale;
FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
alphar[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1)); alphar[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))
alphar[0] = -alphar[0]; alphar[0] = -alphar[0];
@ -1140,7 +1136,7 @@ void lppTransposerHBE(
} else { } else {
INT scale; INT scale;
FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale);
alphai[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1)); alphai[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1));
if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) { if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) {
alphai[0] = -alphai[0]; alphai[0] = -alphai[0];
} }

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -713,7 +713,8 @@ void sbr_dec(
} else { /* (flags & SBRDEC_PS_DECODED) */ } else { /* (flags & SBRDEC_PS_DECODED) */
INT sdiff; INT sdiff;
INT scaleFactorHighBand, scaleFactorLowBand_ov, scaleFactorLowBand_no_ov; INT scaleFactorHighBand, scaleFactorLowBand_ov, scaleFactorLowBand_no_ov,
outScalefactor, outScalefactorR, outScalefactorL;
HANDLE_QMF_FILTER_BANK synQmf = &hSbrDec->qmfDomainOutCh->fb; HANDLE_QMF_FILTER_BANK synQmf = &hSbrDec->qmfDomainOutCh->fb;
HANDLE_QMF_FILTER_BANK synQmfRight = &hSbrDecRight->qmfDomainOutCh->fb; HANDLE_QMF_FILTER_BANK synQmfRight = &hSbrDecRight->qmfDomainOutCh->fb;
@ -744,7 +745,7 @@ void sbr_dec(
*/ */
FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <= FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <=
QMF_MAX_SYNTHESIS_BANDS); QMF_MAX_SYNTHESIS_BANDS);
qmfChangeOutScalefactor(synQmfRight, -(8)); synQmfRight->outScalefactor = synQmf->outScalefactor;
FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates, FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates,
9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis * 9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis *
sizeof(FIXP_QSS)); sizeof(FIXP_QSS));
@ -788,9 +789,11 @@ void sbr_dec(
FDKmemcpy(&hSbrDecRight->sbrDrcChannel, &hSbrDec->sbrDrcChannel, FDKmemcpy(&hSbrDecRight->sbrDrcChannel, &hSbrDec->sbrDrcChannel,
sizeof(SBRDEC_DRC_CHANNEL)); sizeof(SBRDEC_DRC_CHANNEL));
for (i = 0; i < synQmf->no_col; i++) { /* ----- no_col loop ----- */ outScalefactor = maxShift - (8);
outScalefactorL = outScalefactorR =
sbrInDataHeadroom + 1; /* +1: psDiffScale! (MPEG-PS) */
INT outScalefactorR, outScalefactorL; for (i = 0; i < synQmf->no_col; i++) { /* ----- no_col loop ----- */
/* qmf timeslot of right channel */ /* qmf timeslot of right channel */
FIXP_DBL *rQmfReal = pWorkBuffer; FIXP_DBL *rQmfReal = pWorkBuffer;
@ -815,27 +818,20 @@ void sbr_dec(
? scaleFactorLowBand_ov ? scaleFactorLowBand_ov
: scaleFactorLowBand_no_ov, : scaleFactorLowBand_no_ov,
scaleFactorHighBand, synQmf->lsb, synQmf->usb); scaleFactorHighBand, synQmf->lsb, synQmf->usb);
outScalefactorL = outScalefactorR =
1 + sbrInDataHeadroom; /* psDiffScale! (MPEG-PS) */
} }
sbrDecoder_drcApplySlot(/* right channel */ sbrDecoder_drcApplySlot(/* right channel */
&hSbrDecRight->sbrDrcChannel, rQmfReal, &hSbrDecRight->sbrDrcChannel, rQmfReal,
rQmfImag, i, synQmfRight->no_col, maxShift); rQmfImag, i, synQmfRight->no_col, maxShift);
outScalefactorR += maxShift;
sbrDecoder_drcApplySlot(/* left channel */ sbrDecoder_drcApplySlot(/* left channel */
&hSbrDec->sbrDrcChannel, *(pLowBandReal + i), &hSbrDec->sbrDrcChannel, *(pLowBandReal + i),
*(pLowBandImag + i), i, synQmf->no_col, *(pLowBandImag + i), i, synQmf->no_col,
maxShift); maxShift);
outScalefactorL += maxShift;
if (!(flags & SBRDEC_SKIP_QMF_SYN)) { if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
qmfChangeOutScalefactor(synQmf, -(8)); qmfChangeOutScalefactor(synQmf, outScalefactor);
qmfChangeOutScalefactor(synQmfRight, -(8)); qmfChangeOutScalefactor(synQmfRight, outScalefactor);
qmfSynthesisFilteringSlot( qmfSynthesisFilteringSlot(
synQmfRight, rQmfReal, /* QMF real buffer */ synQmfRight, rQmfReal, /* QMF real buffer */

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -233,15 +233,20 @@ void sbrDecoder_drcApplySlot(HANDLE_SBR_DRC_CHANNEL hDrcData,
if (hDrcData->winSequenceCurr != 2) { /* long window */ if (hDrcData->winSequenceCurr != 2) { /* long window */
int j = col + (numQmfSubSamples >> 1); int j = col + (numQmfSubSamples >> 1);
if (j < winBorderToColMap[15]) {
if (hDrcData->drcInterpolationSchemeCurr == 0) { if (hDrcData->drcInterpolationSchemeCurr == 0) {
INT k = (frameLenFlag) ? 0x4444445 : 0x4000000; INT k = (frameLenFlag) ? 0x4444445 : 0x4000000;
alphaValue = (FIXP_DBL)(j * k); alphaValue = (FIXP_DBL)(j * k);
} else { } else {
if (j >= (int)winBorderToColMap[hDrcData->drcInterpolationSchemeCurr]) { if (j >=
(int)winBorderToColMap[hDrcData->drcInterpolationSchemeCurr]) {
alphaValue = (FIXP_DBL)MAXVAL_DBL; alphaValue = (FIXP_DBL)MAXVAL_DBL;
} }
} }
} else {
alphaValue = (FIXP_DBL)MAXVAL_DBL;
}
} else { /* short windows */ } else { /* short windows */
shortDrc = 1; shortDrc = 1;
} }
@ -254,15 +259,20 @@ void sbrDecoder_drcApplySlot(HANDLE_SBR_DRC_CHANNEL hDrcData,
if (hDrcData->winSequenceNext != 2) { /* next: long window */ if (hDrcData->winSequenceNext != 2) { /* next: long window */
int j = col - (numQmfSubSamples >> 1); int j = col - (numQmfSubSamples >> 1);
if (j < winBorderToColMap[15]) {
if (hDrcData->drcInterpolationSchemeNext == 0) { if (hDrcData->drcInterpolationSchemeNext == 0) {
INT k = (frameLenFlag) ? 0x4444445 : 0x4000000; INT k = (frameLenFlag) ? 0x4444445 : 0x4000000;
alphaValue = (FIXP_DBL)(j * k); alphaValue = (FIXP_DBL)(j * k);
} else { } else {
if (j >= (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) { if (j >=
(int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) {
alphaValue = (FIXP_DBL)MAXVAL_DBL; alphaValue = (FIXP_DBL)MAXVAL_DBL;
} }
} }
} else {
alphaValue = (FIXP_DBL)MAXVAL_DBL;
}
fact_mag = hDrcData->nextFact_mag; fact_mag = hDrcData->nextFact_mag;
fact_exp = hDrcData->nextFact_exp; fact_exp = hDrcData->nextFact_exp;
@ -289,15 +299,20 @@ void sbrDecoder_drcApplySlot(HANDLE_SBR_DRC_CHANNEL hDrcData,
if (hDrcData->winSequenceNext != 2) { /* long window */ if (hDrcData->winSequenceNext != 2) { /* long window */
int j = col - (numQmfSubSamples >> 1); int j = col - (numQmfSubSamples >> 1);
if (j < winBorderToColMap[15]) {
if (hDrcData->drcInterpolationSchemeNext == 0) { if (hDrcData->drcInterpolationSchemeNext == 0) {
INT k = (frameLenFlag) ? 0x4444445 : 0x4000000; INT k = (frameLenFlag) ? 0x4444445 : 0x4000000;
alphaValue = (FIXP_DBL)(j * k); alphaValue = (FIXP_DBL)(j * k);
} else { } else {
if (j >= (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) { if (j >=
(int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) {
alphaValue = (FIXP_DBL)MAXVAL_DBL; alphaValue = (FIXP_DBL)MAXVAL_DBL;
} }
} }
} else {
alphaValue = (FIXP_DBL)MAXVAL_DBL;
}
} else { /* short windows */ } else { /* short windows */
shortDrc = 1; shortDrc = 1;
} }

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -765,9 +765,6 @@ resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags) {
sbrdecUpdateLoRes(hFreq->freqBandTable[0], &nBandsLo, hFreq->freqBandTable[1], sbrdecUpdateLoRes(hFreq->freqBandTable[0], &nBandsLo, hFreq->freqBandTable[1],
nBandsHi); nBandsHi);
hFreq->nSfb[0] = nBandsLo;
hFreq->nSfb[1] = nBandsHi;
/* Check index to freqBandTable[0] */ /* Check index to freqBandTable[0] */
if (!(nBandsLo > 0) || if (!(nBandsLo > 0) ||
(nBandsLo > (((hHeaderData->numberOfAnalysisBands == 16) (nBandsLo > (((hHeaderData->numberOfAnalysisBands == 16)
@ -777,6 +774,9 @@ resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags) {
return SBRDEC_UNSUPPORTED_CONFIG; return SBRDEC_UNSUPPORTED_CONFIG;
} }
hFreq->nSfb[0] = nBandsLo;
hFreq->nSfb[1] = nBandsHi;
lsb = hFreq->freqBandTable[0][0]; lsb = hFreq->freqBandTable[0][0];
usb = hFreq->freqBandTable[0][nBandsLo]; usb = hFreq->freqBandTable[0][nBandsLo];
@ -814,15 +814,15 @@ resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags) {
if (intTemp == 0) intTemp = 1; if (intTemp == 0) intTemp = 1;
if (intTemp > MAX_NOISE_COEFFS) {
return SBRDEC_UNSUPPORTED_CONFIG;
}
hFreq->nNfb = intTemp; hFreq->nNfb = intTemp;
} }
hFreq->nInvfBands = hFreq->nNfb; hFreq->nInvfBands = hFreq->nNfb;
if (hFreq->nNfb > MAX_NOISE_COEFFS) {
return SBRDEC_UNSUPPORTED_CONFIG;
}
/* Get noise bands */ /* Get noise bands */
sbrdecDownSampleLoRes(hFreq->freqBandTableNoise, hFreq->nNfb, sbrdecDownSampleLoRes(hFreq->freqBandTableNoise, hFreq->nNfb,
hFreq->freqBandTable[0], nBandsLo); hFreq->freqBandTable[0], nBandsLo);

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -961,10 +961,12 @@ SBR_ERROR sbrDecoder_SetParam(HANDLE_SBRDECODER self, const SBRDEC_PARAM param,
/* Set sync state UPSAMPLING for the corresponding slot. /* Set sync state UPSAMPLING for the corresponding slot.
This switches off bitstream parsing until a new header arrives. */ This switches off bitstream parsing until a new header arrives. */
if (hSbrHeader->syncState != SBR_NOT_INITIALIZED) {
hSbrHeader->syncState = UPSAMPLING; hSbrHeader->syncState = UPSAMPLING;
hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE; hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE;
} }
} }
}
} break; } break;
case SBR_SKIP_QMF: case SBR_SKIP_QMF:
@ -1371,7 +1373,9 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
} }
if (headerStatus == HEADER_ERROR) { if (headerStatus == HEADER_ERROR) {
/* Corrupt SBR info data, do not decode and switch to UPSAMPLING */ /* Corrupt SBR info data, do not decode and switch to UPSAMPLING */
hSbrHeader->syncState = UPSAMPLING; hSbrHeader->syncState = hSbrHeader->syncState > UPSAMPLING
? UPSAMPLING
: hSbrHeader->syncState;
fDoDecodeSbrData = 0; fDoDecodeSbrData = 0;
sbrHeaderPresent = 0; sbrHeaderPresent = 0;
} }
@ -1610,8 +1614,10 @@ static SBR_ERROR sbrDecoder_DecodeElement(
/* No valid SBR payload available, hence switch to upsampling (in all /* No valid SBR payload available, hence switch to upsampling (in all
* headers) */ * headers) */
for (hdrIdx = 0; hdrIdx < ((1) + 1); hdrIdx += 1) { for (hdrIdx = 0; hdrIdx < ((1) + 1); hdrIdx += 1) {
if (self->sbrHeader[elementIndex][hdrIdx].syncState > UPSAMPLING) {
self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING; self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING;
} }
}
} else { } else {
/* Move frame pointer to the next slot which is up to be decoded/applied /* Move frame pointer to the next slot which is up to be decoded/applied
* next */ * next */

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -1267,6 +1267,7 @@ void FDKsbrEnc_extractSbrEnvelope2(
sbrExtrEnv->pre_transient_info[1] = ed->transient_info[1]; /* tran_flag */ sbrExtrEnv->pre_transient_info[1] = ed->transient_info[1]; /* tran_flag */
hEnvChan->encEnvData.noOfEnvelopes = ed->nEnvelopes = hEnvChan->encEnvData.noOfEnvelopes = ed->nEnvelopes =
ed->frame_info->nEnvelopes; /* number of envelopes of current frame */ ed->frame_info->nEnvelopes; /* number of envelopes of current frame */
hEnvChan->encEnvData.currentAmpResFF = (AMP_RES)h_con->initAmpResFF;
/* /*
Check if the current frame is divided into one envelope only. If so, set Check if the current frame is divided into one envelope only. If so, set
@ -1274,8 +1275,9 @@ void FDKsbrEnc_extractSbrEnvelope2(
*/ */
if ((hEnvChan->encEnvData.hSbrBSGrid->frameClass == FIXFIX) && if ((hEnvChan->encEnvData.hSbrBSGrid->frameClass == FIXFIX) &&
(ed->nEnvelopes == 1)) { (ed->nEnvelopes == 1)) {
AMP_RES currentAmpResFF = SBR_AMP_RES_1_5;
if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
/* Note: global_tonaliy_float_value == /* Note: global_tonality_float_value ==
((float)hEnvChan->encEnvData.global_tonality/((INT64)(1)<<(31-(19+2)))/0.524288*(2.0/3.0))); ((float)hEnvChan->encEnvData.global_tonality/((INT64)(1)<<(31-(19+2)))/0.524288*(2.0/3.0)));
threshold_float_value == threshold_float_value ==
((float)h_con->thresholdAmpResFF_m/((INT64)(1)<<(31-(h_con->thresholdAmpResFF_e)))/0.524288*(2.0/3.0))); ((float)h_con->thresholdAmpResFF_m/((INT64)(1)<<(31-(h_con->thresholdAmpResFF_e)))/0.524288*(2.0/3.0)));
@ -1289,14 +1291,13 @@ void FDKsbrEnc_extractSbrEnvelope2(
} else { } else {
hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0; hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0;
} }
} else currentAmpResFF = hEnvChan->encEnvData.currentAmpResFF;
hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5; }
if (hEnvChan->encEnvData.currentAmpResFF != if (currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) {
hEnvChan->encEnvData.init_sbr_amp_res) {
FDKsbrEnc_InitSbrHuffmanTables( FDKsbrEnc_InitSbrHuffmanTables(
&hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope, &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope,
&hEnvChan->sbrCodeNoiseFloor, hEnvChan->encEnvData.currentAmpResFF); &hEnvChan->sbrCodeNoiseFloor, currentAmpResFF);
} }
} else { } else {
if (sbrHeaderData->sbr_amp_res != hEnvChan->encEnvData.init_sbr_amp_res) { if (sbrHeaderData->sbr_amp_res != hEnvChan->encEnvData.init_sbr_amp_res) {
@ -1355,6 +1356,13 @@ void FDKsbrEnc_extractSbrEnvelope2(
} }
} }
if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY &&
stereoMode == SBR_SWITCH_LRC &&
h_envChan[0]->encEnvData.currentAmpResFF !=
h_envChan[1]->encEnvData.currentAmpResFF) {
stereoMode = SBR_LEFT_RIGHT;
}
/* /*
Extract envelope of current frame. Extract envelope of current frame.
*/ */

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -1450,8 +1450,6 @@ static INT initEnvChannel(HANDLE_SBR_CONFIG_DATA sbrConfigData,
params->deltaTAcrossFrames, 0, 0)) params->deltaTAcrossFrames, 0, 0))
return (1); return (1);
sbrConfigData->initAmpResFF = params->init_amp_res_FF;
if (FDKsbrEnc_InitSbrHuffmanTables(&hEnv->encEnvData, &hEnv->sbrCodeEnvelope, if (FDKsbrEnc_InitSbrHuffmanTables(&hEnv->encEnvData, &hEnv->sbrCodeEnvelope,
&hEnv->sbrCodeNoiseFloor, &hEnv->sbrCodeNoiseFloor,
sbrHeaderData->sbr_amp_res)) sbrHeaderData->sbr_amp_res))
@ -1749,6 +1747,7 @@ static INT FDKsbrEnc_EnvInit(HANDLE_SBR_ELEMENT hSbrElement,
hSbrElement->sbrHeaderData.sbr_data_extra = 1; hSbrElement->sbrHeaderData.sbr_data_extra = 1;
hSbrElement->sbrHeaderData.sbr_amp_res = (AMP_RES)params->amp_res; hSbrElement->sbrHeaderData.sbr_amp_res = (AMP_RES)params->amp_res;
hSbrElement->sbrConfigData.initAmpResFF = params->init_amp_res_FF;
/* header_extra_1 */ /* header_extra_1 */
hSbrElement->sbrHeaderData.freqScale = params->freqScale; hSbrElement->sbrHeaderData.freqScale = params->freqScale;