aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--documentation/aacDecoder.pdfbin490978 -> 492288 bytes
-rw-r--r--documentation/aacEncoder.pdfbin443728 -> 443831 bytes
-rw-r--r--libAACdec/include/aacdecoder_lib.h2
-rw-r--r--libAACdec/src/aacdecoder.cpp136
-rw-r--r--libAACdec/src/aacdecoder_lib.cpp7
-rw-r--r--libAACdec/src/rvlc.cpp15
-rw-r--r--libAACenc/include/aacenc_lib.h4
-rw-r--r--libAACenc/src/aacenc_lib.cpp7
-rw-r--r--libDRCdec/src/drcDec_reader.cpp4
-rw-r--r--libFDK/src/autocorr2nd.cpp43
-rw-r--r--libMpegTPDec/src/tpdec_latm.cpp41
-rw-r--r--libMpegTPDec/src/tpdec_latm.h4
-rw-r--r--libPCMutils/src/pcmdmx_lib.cpp56
-rw-r--r--libSACdec/src/sac_process.cpp20
-rw-r--r--libSACdec/src/sac_reshapeBBEnv.cpp77
-rw-r--r--libSACdec/src/sac_stp.cpp26
-rw-r--r--libSBRdec/src/env_calc.cpp31
-rw-r--r--libSBRdec/src/hbe.cpp51
-rw-r--r--libSBRdec/src/lpp_tran.cpp20
-rw-r--r--libSBRdec/src/sbrdec_freq_sca.cpp16
-rw-r--r--libSBRdec/src/sbrdecoder.cpp16
21 files changed, 355 insertions, 221 deletions
diff --git a/documentation/aacDecoder.pdf b/documentation/aacDecoder.pdf
index cc7cf41..3d4699e 100644
--- a/documentation/aacDecoder.pdf
+++ b/documentation/aacDecoder.pdf
Binary files differ
diff --git a/documentation/aacEncoder.pdf b/documentation/aacEncoder.pdf
index 77b8f4c..a47708a 100644
--- a/documentation/aacEncoder.pdf
+++ b/documentation/aacEncoder.pdf
Binary files differ
diff --git a/libAACdec/include/aacdecoder_lib.h b/libAACdec/include/aacdecoder_lib.h
index 56f4ec1..d7928c0 100644
--- a/libAACdec/include/aacdecoder_lib.h
+++ b/libAACdec/include/aacdecoder_lib.h
@@ -1032,7 +1032,7 @@ LINKSPEC_H AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self,
* \param self AAC decoder handle.
* \param pTimeData Pointer to external output buffer where the decoded PCM
* 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
* (flags & AACDEC_CONCEAL) == 1: Do concealment. \n
* (flags & AACDEC_FLUSH) == 2: Discard input data. Flush
diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp
index c18e5e9..d5f0cea 100644
--- a/libAACdec/src/aacdecoder.cpp
+++ b/libAACdec/src/aacdecoder.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -494,6 +494,75 @@ static AAC_DECODER_ERROR CDataStreamElement_Read(HANDLE_AACDECODER self,
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
@@ -1417,11 +1486,7 @@ static void CAacDecoder_AcceptFlags(HANDLE_AACDECODER self,
const CSAudioSpecificConfig *asc,
UINT flags, UINT *elFlags, int streamIndex,
int elementOffset) {
- {
- FDKmemcpy(
- self->elFlags, elFlags,
- sizeof(*elFlags) * (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1));
- }
+ FDKmemcpy(self->elFlags, elFlags, sizeof(self->elFlags));
self->flags[streamIndex] = flags;
}
@@ -1524,8 +1589,14 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
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;
UCHAR downscaleFactor = self->downscaleFactor;
@@ -1709,7 +1780,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
asc->m_sc.m_usacConfig.m_usacNumElements;
}
- self->mpsEnableCurr = 0;
+ mpsEnableCurr = 0;
for (int _el = 0;
_el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements;
_el++) {
@@ -1729,7 +1800,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
self->usacStereoConfigIndex[el] =
asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex;
if (self->elements[el] == ID_USAC_CPE) {
- self->mpsEnableCurr |= self->usacStereoConfigIndex[el] ? 1 : 0;
+ mpsEnableCurr |= self->usacStereoConfigIndex[el] ? 1 : 0;
}
}
@@ -1865,7 +1936,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
self->useLdQmfTimeAlign =
asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign;
}
- if (self->sbrEnabled != asc->m_sbrPresentFlag) {
+ if (sbrEnabled != asc->m_sbrPresentFlag) {
ascChanged = 1;
}
}
@@ -1881,13 +1952,13 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
flags |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0;
flags |= (asc->m_psPresentFlag) ? AC_PS_PRESENT : 0;
if (asc->m_sbrPresentFlag) {
- self->sbrEnabled = 1;
- self->sbrEnabledPrev = 1;
+ sbrEnabled = 1;
+ sbrEnabledPrev = 1;
} else {
- self->sbrEnabled = 0;
- self->sbrEnabledPrev = 0;
+ sbrEnabled = 0;
+ sbrEnabledPrev = 0;
}
- if (self->sbrEnabled && asc->m_extensionSamplingFrequency) {
+ if (sbrEnabled && asc->m_extensionSamplingFrequency) {
if (downscaleFactor != 1 && (downscaleFactor)&1) {
return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* SBR needs an even downscale
factor */
@@ -1914,7 +1985,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
flags |= (asc->m_hcrFlag) ? AC_ER_HCR : 0;
if (asc->m_aot == AOT_ER_AAC_ELD) {
- self->mpsEnableCurr = 0;
+ mpsEnableCurr = 0;
flags |= AC_ELD;
flags |= (asc->m_sbrPresentFlag)
? AC_SBR_PRESENT
@@ -1925,7 +1996,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
? AC_MPS_PRESENT
: 0;
if (self->mpsApplicable) {
- self->mpsEnableCurr = asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign;
+ mpsEnableCurr = asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign;
}
}
flags |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0;
@@ -2006,7 +2077,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
/* set AC_USAC_SCFGI3 globally if any usac element uses */
switch (asc->m_aot) {
case AOT_USAC:
- if (self->sbrEnabled) {
+ if (sbrEnabled) {
for (int _el = 0;
_el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements;
_el++) {
@@ -2043,7 +2114,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
*/
switch (asc->m_aot) {
case AOT_USAC:
- if (self->sbrEnabled) {
+ if (sbrEnabled) {
const UCHAR map_sbrRatio_2_nAnaBands[] = {16, 24, 32};
FDK_ASSERT(asc->m_sc.m_usacConfig.m_sbrRatioIndex > 0);
@@ -2071,11 +2142,11 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
}
break;
case AOT_ER_AAC_ELD:
- if (self->mpsEnableCurr &&
+ if (mpsEnableCurr &&
asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) {
- SAC_INPUT_CONFIG sac_interface =
- (self->sbrEnabled && self->hSbrDecoder) ? SAC_INTERFACE_QMF
- : SAC_INTERFACE_TIME;
+ SAC_INPUT_CONFIG sac_interface = (sbrEnabled && self->hSbrDecoder)
+ ? SAC_INTERFACE_QMF
+ : SAC_INTERFACE_TIME;
mpegSurroundDecoder_ConfigureQmfDomain(
(CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface,
(UINT)self->streamInfo.aacSampleRate, asc->m_aot);
@@ -2430,6 +2501,9 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
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];
@@ -2968,6 +3042,24 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
} /* 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))) {
/* float decoder checks if bitsLeft is in range 0-7; only prerollAUs are
* byteAligned with respect to the first bit */
diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp
index 9d36d10..0c83191 100644
--- a/libAACdec/src/aacdecoder_lib.cpp
+++ b/libAACdec/src/aacdecoder_lib.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -1626,6 +1626,11 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self,
/* set params */
sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY,
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);
diff --git a/libAACdec/src/rvlc.cpp b/libAACdec/src/rvlc.cpp
index b7a9be1..0b80364 100644
--- a/libAACdec/src/rvlc.cpp
+++ b/libAACdec/src/rvlc.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -628,7 +628,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd;
SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
- UCHAR *pEscEscCnt = &(pRvlc->numDecodedEscapeWordsEsc);
+ UCHAR escEscCnt = pRvlc->numDecodedEscapeWordsEsc;
UCHAR *pEscBwdCnt = &(pRvlc->numDecodedEscapeWordsBwd);
pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_bwd);
@@ -636,7 +636,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
*pEscBwdCnt = 0;
pRvlc->direction = BWD;
- pScfEsc += *pEscEscCnt - 1; /* set pScfEsc to last entry */
+ pScfEsc += escEscCnt - 1; /* set pScfEsc to last entry */
pRvlc->firstScf = 0;
pRvlc->firstNrg = 0;
pRvlc->firstIs = 0;
@@ -651,7 +651,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
}
dpcm -= TABLE_OFFSET;
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;
return;
} else {
@@ -694,7 +694,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
}
dpcm -= TABLE_OFFSET;
if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
- if (pRvlc->length_of_rvlc_escapes) {
+ if ((pRvlc->length_of_rvlc_escapes) || (*pEscBwdCnt >= escEscCnt)) {
pScfBwd[bnds] = position;
pRvlc->conceal_min = fMax(0, bnds - offset);
return;
@@ -731,7 +731,8 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
}
dpcm -= TABLE_OFFSET;
if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
- if (pRvlc->length_of_rvlc_escapes) {
+ if ((pRvlc->length_of_rvlc_escapes) ||
+ (*pEscBwdCnt >= escEscCnt)) {
pScfBwd[bnds] = noisenrg;
pRvlc->conceal_min = fMax(0, bnds - offset);
return;
@@ -762,7 +763,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
}
dpcm -= TABLE_OFFSET;
if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
- if (pRvlc->length_of_rvlc_escapes) {
+ if ((pRvlc->length_of_rvlc_escapes) || (*pEscBwdCnt >= escEscCnt)) {
pScfBwd[bnds] = factor;
pRvlc->conceal_min = fMax(0, bnds - offset);
return;
diff --git a/libAACenc/include/aacenc_lib.h b/libAACenc/include/aacenc_lib.h
index 71f7556..f0f23b4 100644
--- a/libAACenc/include/aacenc_lib.h
+++ b/libAACenc/include/aacenc_lib.h
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -1643,7 +1643,7 @@ AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder,
*
* \return
* - 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_InfoStruct *pInfo);
diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp
index caa62c5..c11db27 100644
--- a/libAACenc/src/aacenc_lib.cpp
+++ b/libAACenc/src/aacenc_lib.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -2521,6 +2521,11 @@ AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER hAacEncoder,
AACENC_InfoStruct *pInfo) {
AACENC_ERROR err = AACENC_OK;
+ if ((hAacEncoder == NULL) || (pInfo == NULL)) {
+ err = AACENC_INVALID_HANDLE;
+ goto bail;
+ }
+
FDKmemclear(pInfo, sizeof(AACENC_InfoStruct));
pInfo->confSize = 64; /* pre-initialize */
diff --git a/libDRCdec/src/drcDec_reader.cpp b/libDRCdec/src/drcDec_reader.cpp
index b3ec187..b080f50 100644
--- a/libDRCdec/src/drcDec_reader.cpp
+++ b/libDRCdec/src/drcDec_reader.cpp
@@ -917,7 +917,7 @@ static void _skipEqCoefficients(HANDLE_FDK_BITSTREAM hBs) {
firFilterOrder;
int uniqueEqSubbandGainsCount, eqSubbandGainRepresentation,
eqSubbandGainCount;
- EQ_SUBBAND_GAIN_FORMAT eqSubbandGainFormat;
+ int eqSubbandGainFormat;
eqDelayMaxPresent = FDKreadBits(hBs, 1);
if (eqDelayMaxPresent) {
@@ -958,7 +958,7 @@ static void _skipEqCoefficients(HANDLE_FDK_BITSTREAM hBs) {
uniqueEqSubbandGainsCount = FDKreadBits(hBs, 6);
if (uniqueEqSubbandGainsCount > 0) {
eqSubbandGainRepresentation = FDKreadBits(hBs, 1);
- eqSubbandGainFormat = (EQ_SUBBAND_GAIN_FORMAT)FDKreadBits(hBs, 4);
+ eqSubbandGainFormat = FDKreadBits(hBs, 4);
switch (eqSubbandGainFormat) {
case GF_QMF32:
eqSubbandGainCount = 32;
diff --git a/libFDK/src/autocorr2nd.cpp b/libFDK/src/autocorr2nd.cpp
index 718a555..8c5673c 100644
--- a/libFDK/src/autocorr2nd.cpp
+++ b/libFDK/src/autocorr2nd.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -102,11 +102,6 @@ amm-info@iis.fraunhofer.de
#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
@@ -126,45 +121,49 @@ INT autoCorr2nd_real(
const FIXP_DBL *realBuf = reBuffer;
+ const int len_scale = fMax(DFRACT_BITS - fNormz((FIXP_DBL)(len / 2)), 1);
/*
r11r,r22r
r01r,r12r
r02r
*/
pReBuf = realBuf - 2;
- accu5 = ((fMultDiv2(pReBuf[0], pReBuf[2]) + fMultDiv2(pReBuf[1], pReBuf[3]))
- SHIFT);
+ accu5 =
+ ((fMultDiv2(pReBuf[0], pReBuf[2]) + fMultDiv2(pReBuf[1], pReBuf[3])) >>
+ len_scale);
pReBuf++;
/* len must be even */
- accu1 = fPow2Div2(pReBuf[0]) SHIFT;
- accu3 = fMultDiv2(pReBuf[0], pReBuf[1]) SHIFT;
+ accu1 = fPow2Div2(pReBuf[0]) >> len_scale;
+ accu3 = fMultDiv2(pReBuf[0], pReBuf[1]) >> len_scale;
pReBuf++;
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]) +
- fMultDiv2(pReBuf[1], pReBuf[2])) SHIFT);
+ accu3 +=
+ ((fMultDiv2(pReBuf[0], pReBuf[1]) + fMultDiv2(pReBuf[1], pReBuf[2])) >>
+ len_scale);
- accu5 += ((fMultDiv2(pReBuf[0], pReBuf[2]) +
- fMultDiv2(pReBuf[1], pReBuf[3])) SHIFT);
+ accu5 +=
+ ((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;
- 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;
- accu3 += (fMultDiv2(realBuf[len - 1], realBuf[len - 2]) SHIFT);
+ accu3 += (fMultDiv2(realBuf[len - 1], realBuf[len - 2]) >> len_scale);
mScale = CntLeadingZeros(
(accu1 | accu2 | fAbs(accu3) | fAbs(accu4) | fAbs(accu5))) -
1;
- autoCorrScaling = mScale - 1 - SHIFT_FACTOR; /* -1 because of fMultDiv2*/
+ autoCorrScaling = mScale - 1 - len_scale; /* -1 because of fMultDiv2*/
/* Scale to common scale factor */
ac->r11r = accu1 << mScale;
@@ -190,7 +189,7 @@ INT autoCorr2nd_cplx(
const FIXP_DBL *imBuffer, /*!< Pointer to imag part of input samples */
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;
@@ -199,7 +198,7 @@ INT autoCorr2nd_cplx(
const FIXP_DBL *realBuf = reBuffer;
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,
r11r,r22r
diff --git a/libMpegTPDec/src/tpdec_latm.cpp b/libMpegTPDec/src/tpdec_latm.cpp
index 3b71db8..c32be54 100644
--- a/libMpegTPDec/src/tpdec_latm.cpp
+++ b/libMpegTPDec/src/tpdec_latm.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -591,6 +591,18 @@ bail:
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,
CLatmDemux *pLatmDemux) {
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);
for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
LATM_LAYER_INFO *p_linfo = &pLatmDemux->m_linfo[prog][lay];
+ int auChunkLengthInfo = 0;
switch (p_linfo->m_frameLengthType) {
case 0:
- p_linfo->m_frameLengthInBits = CLatmDemux_ReadAuChunkLengthInfo(bs);
- totalPayloadBits += p_linfo->m_frameLengthInBits;
+ auChunkLengthInfo = CLatmDemux_ReadAuChunkLengthInfo(bs);
+ if (auChunkLengthInfo >= 0) {
+ p_linfo->m_frameLengthInBits = (UINT)auChunkLengthInfo;
+ totalPayloadBits += p_linfo->m_frameLengthInBits;
+ } else {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
break;
case 3:
case 5:
@@ -627,23 +645,6 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs,
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,
const UINT layer) {
UINT nFrameLenBits = 0;
diff --git a/libMpegTPDec/src/tpdec_latm.h b/libMpegTPDec/src/tpdec_latm.h
index 6af553d..8b8c971 100644
--- a/libMpegTPDec/src/tpdec_latm.h
+++ b/libMpegTPDec/src/tpdec_latm.h
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -151,8 +151,6 @@ typedef struct {
AudioPreRoll */
} CLatmDemux;
-int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs);
-
TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs,
CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt,
CSTpCallBacks *pTpDecCallbacks,
diff --git a/libPCMutils/src/pcmdmx_lib.cpp b/libPCMutils/src/pcmdmx_lib.cpp
index 2070dbc..fca12ce 100644
--- a/libPCMutils/src/pcmdmx_lib.cpp
+++ b/libPCMutils/src/pcmdmx_lib.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -494,13 +494,40 @@ static PCM_DMX_CHANNEL_MODE getChMode4Plain(
return plainChMode;
}
-static inline UINT getIdxSum(UCHAR numCh) {
- UINT result = 0;
- int i;
- for (i = 1; i < numCh; i += 1) {
- result += i;
+/** Validates the channel indices of all channels present in the bitstream.
+ * The channel indices have to be consecutive and unique for each audio channel
+ *type.
+ * @param [in] The total number of channels of the given configuration.
+ * @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 */
+ }
+ }
+ }
+ }
+ if (found == FALSE) {
+ return 0; /* Did not find channel index */
+ }
}
- return result;
+ return 1; /* Successfully validated channel indices */
}
/** Evaluate a given channel configuration and extract a packed channel mode. In
@@ -523,7 +550,6 @@ static PCMDMX_ERROR getChannelMode(
UCHAR offsetTable[(8)], /* out */
PCM_DMX_CHANNEL_MODE *chMode /* out */
) {
- UINT idxSum[(3)][(4)];
UCHAR numCh[(3)][(4)];
UCHAR mapped[(8)];
PCM_DMX_SPEAKER_POSITION spkrPos[(8)];
@@ -538,7 +564,6 @@ static PCMDMX_ERROR getChannelMode(
FDK_ASSERT(chMode != NULL);
/* 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(mapped, (8) * sizeof(UCHAR));
FDKmemclear(spkrPos, (8) * sizeof(PCM_DMX_SPEAKER_POSITION));
@@ -552,19 +577,22 @@ static PCMDMX_ERROR getChannelMode(
(channelType[ch] & 0x0F) - 1,
0); /* Assign all undefined channels (ACT_NONE) to front channels. */
numCh[channelType[ch] >> 4][chGrp] += 1;
- idxSum[channelType[ch] >> 4][chGrp] += channelIndices[ch];
}
- if (numChannels > TWO_CHANNEL) {
+
+ {
int chGrp;
/* Sanity check on the indices */
for (chGrp = 0; chGrp < (4); chGrp += 1) {
int plane;
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;
for (ch = 0; ch < numChannels; ch += 1) {
- if (channelType[ch] ==
- (AUDIO_CHANNEL_TYPE)((plane << 4) | ((chGrp + 1) & 0xF))) {
+ if (channelType[ch] == aChType) {
channelIndices[ch] = idxCnt++;
}
}
diff --git a/libSACdec/src/sac_process.cpp b/libSACdec/src/sac_process.cpp
index 22091a9..33a1647 100644
--- a/libSACdec/src/sac_process.cpp
+++ b/libSACdec/src/sac_process.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -517,12 +517,11 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
maxVal = fAbs(iReal0) | fAbs(iImag0);
maxVal |= fAbs(iReal1);
- s = fMax(CntLeadingZeros(maxVal) - 1, 0);
- s = fMin(s, scale_param_m2);
+ s = fMin(CntLeadingZeros(maxVal) - 2, scale_param_m2);
- mReal0 = iReal0 << s;
- mImag0 = iImag0 << s;
- mReal1 = iReal1 << s;
+ mReal0 = scaleValue(iReal0, s);
+ mImag0 = scaleValue(iImag0, s);
+ mReal1 = scaleValue(iReal1, s);
s = scale_param_m2 - s;
@@ -562,12 +561,11 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
maxVal = fAbs(iReal0) | fAbs(iImag0);
maxVal |= fAbs(iReal1);
- s = fMax(CntLeadingZeros(maxVal) - 1, 0);
- s = fMin(s, scale_param_m2);
+ s = fMin(CntLeadingZeros(maxVal) - 2, scale_param_m2);
- mReal0 = FX_DBL2FX_SGL(iReal0 << s);
- mImag0 = FX_DBL2FX_SGL(iImag0 << s);
- mReal1 = FX_DBL2FX_SGL(iReal1 << s);
+ mReal0 = FX_DBL2FX_SGL(scaleValue(iReal0, s));
+ mImag0 = FX_DBL2FX_SGL(scaleValue(iImag0, s));
+ mReal1 = FX_DBL2FX_SGL(scaleValue(iReal1, s));
s = scale_param_m2 - s;
diff --git a/libSACdec/src/sac_reshapeBBEnv.cpp b/libSACdec/src/sac_reshapeBBEnv.cpp
index 272d009..72f4e58 100644
--- a/libSACdec/src/sac_reshapeBBEnv.cpp
+++ b/libSACdec/src/sac_reshapeBBEnv.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -241,29 +241,56 @@ static inline void combineDryWet(FIXP_DBL *RESTRICT pReal,
}
}
-static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry,
- FIXP_DBL *RESTRICT slotAmp_wet,
- FIXP_DBL *RESTRICT pHybOutputRealDry,
- FIXP_DBL *RESTRICT pHybOutputImagDry,
- FIXP_DBL *RESTRICT pHybOutputRealWet,
- FIXP_DBL *RESTRICT pHybOutputImagWet, INT cplxBands,
- INT hybBands) {
- INT qs;
+static inline void slotAmp(
+ FIXP_DBL *RESTRICT slotAmp_dry, INT *RESTRICT slotAmp_dry_e,
+ FIXP_DBL *RESTRICT slotAmp_wet, INT *RESTRICT slotAmp_wet_e,
+ FIXP_DBL *RESTRICT pHybOutputRealDry, FIXP_DBL *RESTRICT pHybOutputImagDry,
+ FIXP_DBL *RESTRICT pHybOutputRealWet, FIXP_DBL *RESTRICT pHybOutputImagWet,
+ INT cplxBands, INT hybBands) {
+ INT qs, s1, s2, headroom_dry, headroom_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);
for (qs = 0; qs < cplxBands; qs++) {
- dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)) +
- fPow2Div2(pHybOutputImagDry[qs] << (1)));
- wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)) +
- fPow2Div2(pHybOutputImagWet[qs] << (1)));
+ /* sum up dry part */
+ dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
+ dry += (fPow2Div2(pHybOutputImagDry[qs] << headroom_dry) >> s1);
+ /* sum up wet part */
+ wet += (fPow2Div2(pHybOutputRealWet[qs] << headroom_wet) >> s1);
+ wet += (fPow2Div2(pHybOutputImagWet[qs] << headroom_wet) >> s1);
}
for (; qs < hybBands; qs++) {
- dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)));
- wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)));
+ dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
+ 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__)
@@ -533,6 +560,7 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
INT ts) {
INT ch, scale;
INT dryFacSF, slotAmpSF;
+ INT slotAmp_dry_e, slotAmp_wet_e;
FIXP_DBL tmp, dryFac, envShape;
FIXP_DBL slotAmp_dry, slotAmp_wet, slotAmp_ratio;
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;
}
+ slotAmp_dry_e = slotAmp_wet_e = 0;
+
/* 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->hybOutputRealWet__FDK[ch][6],
&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 */
if (slotAmp_dry != FL2FXCONST_DBL(0.0f)) {
- sc = fixMax(0, CntLeadingZeros(slotAmp_wet) - 1);
- sc = sc - (sc & 1);
-
- slotAmp_wet = sqrtFixp(slotAmp_wet << sc);
+ slotAmp_wet = sqrtFixp(slotAmp_wet);
slotAmp_dry = invSqrtNorm2(slotAmp_dry, &slotAmpSF);
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 */
diff --git a/libSACdec/src/sac_stp.cpp b/libSACdec/src/sac_stp.cpp
index b328c82..0e6affa 100644
--- a/libSACdec/src/sac_stp.cpp
+++ b/libSACdec/src/sac_stp.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -229,15 +229,13 @@ inline void combineSignalCplxScale1(FIXP_DBL *hybOutputRealDry,
int n;
FIXP_DBL scaleY;
for (n = bands - 1; n >= 0; n--) {
- scaleY = fMultDiv2(scaleX, *pBP);
+ scaleY = fMult(scaleX, *pBP);
*hybOutputRealDry = SATURATE_LEFT_SHIFT(
- (*hybOutputRealDry >> 1) +
- (fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 1)),
- 1, DFRACT_BITS);
+ (*hybOutputRealDry >> SF_SCALE) + fMult(*hybOutputRealWet, scaleY),
+ SF_SCALE, DFRACT_BITS);
*hybOutputImagDry = SATURATE_LEFT_SHIFT(
- (*hybOutputImagDry >> 1) +
- (fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 1)),
- 1, DFRACT_BITS);
+ (*hybOutputImagDry >> SF_SCALE) + fMult(*hybOutputImagWet, scaleY),
+ SF_SCALE, DFRACT_BITS);
hybOutputRealDry++, hybOutputRealWet++;
hybOutputImagDry++, hybOutputImagWet++;
pBP++;
@@ -252,12 +250,12 @@ inline void combineSignalCplxScale2(FIXP_DBL *hybOutputRealDry,
int n;
for (n = bands - 1; n >= 0; n--) {
- *hybOutputRealDry =
- *hybOutputRealDry +
- (fMultDiv2(*hybOutputRealWet, scaleX) << (SF_SCALE + 1));
- *hybOutputImagDry =
- *hybOutputImagDry +
- (fMultDiv2(*hybOutputImagWet, scaleX) << (SF_SCALE + 1));
+ *hybOutputRealDry = SATURATE_LEFT_SHIFT(
+ (*hybOutputRealDry >> SF_SCALE) + fMult(*hybOutputRealWet, scaleX),
+ SF_SCALE, DFRACT_BITS);
+ *hybOutputImagDry = SATURATE_LEFT_SHIFT(
+ (*hybOutputImagDry >> SF_SCALE) + fMult(*hybOutputImagWet, scaleX),
+ SF_SCALE, DFRACT_BITS);
hybOutputRealDry++, hybOutputRealWet++;
hybOutputImagDry++, hybOutputImagWet++;
}
diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp
index ad5edfe..cefa612 100644
--- a/libSBRdec/src/env_calc.cpp
+++ b/libSBRdec/src/env_calc.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
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[i] = sqrtFixp_lookup(gain[i], &gain_sf[i]);
if (gain_sf[i] < 0) {
- gain[i] >>= -gain_sf[i];
+ gain[i] >>= fMin(DFRACT_BITS - 1, -gain_sf[i]);
gain_sf[i] = 0;
}
} else {
@@ -683,11 +683,6 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
/* gain[i] = g_inter[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); */
FIXP_DBL one = (FIXP_DBL)MAXVAL_DBL >>
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;
for (i = 0; i < nbSubsample; ++i) {
- gain[i] = fMult(gain[i], gain_adj);
- gain_sf[i] += gain_adj_sf;
-
- /* limit gain */
- if (gain_sf[i] > INTER_TES_SF_CHANGE) {
- 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];
+ int gain_e = fMax(
+ fMin(gain_sf[i] + gain_adj_sf - INTER_TES_SF_CHANGE, DFRACT_BITS - 1),
+ -(DFRACT_BITS - 1));
+ FIXP_DBL gain_final = fMult(gain[i], gain_adj);
+ gain_final = scaleValueSaturate(gain_final, gain_e);
for (j = lowSubband; j < highSubband; j++) {
- qmfReal[startPos + i][j] = fMult(qmfReal[startPos + i][j], gain[i]);
- qmfImag[startPos + i][j] = fMult(qmfImag[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_final);
}
}
} else { /* gamma_idx == 0 */
diff --git a/libSBRdec/src/hbe.cpp b/libSBRdec/src/hbe.cpp
index d210bb6..f2452ea 100644
--- a/libSBRdec/src/hbe.cpp
+++ b/libSBRdec/src/hbe.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -1400,42 +1400,27 @@ void QmfTransposerApply(HANDLE_HBE_TRANSPOSER hQmfTransposer,
if (shift_ov != 0) {
for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) {
- for (band = 0; band < QMF_SYNTH_CHANNELS; band++) {
- if (shift_ov >= 0) {
- hQmfTransposer->qmfHBEBufReal_F[i][band] <<= shift_ov;
- hQmfTransposer->qmfHBEBufImag_F[i][band] <<= shift_ov;
- } else {
- hQmfTransposer->qmfHBEBufReal_F[i][band] >>= (-shift_ov);
- hQmfTransposer->qmfHBEBufImag_F[i][band] >>= (-shift_ov);
- }
- }
+ scaleValuesSaturate(&hQmfTransposer->qmfHBEBufReal_F[i][0],
+ QMF_SYNTH_CHANNELS, shift_ov);
+ scaleValuesSaturate(&hQmfTransposer->qmfHBEBufImag_F[i][0],
+ QMF_SYNTH_CHANNELS, shift_ov);
}
- }
- if ((keepStatesSyncedMode == KEEP_STATES_SYNCED_OFF) && shift_ov != 0) {
- for (i = timeStep * firstSlotOffsset; i < ov_len; i++) {
- for (band = hQmfTransposer->startBand; band < hQmfTransposer->stopBand;
- band++) {
- if (shift_ov >= 0) {
- ppQmfBufferOutReal_F[i][band] <<= shift_ov;
- ppQmfBufferOutImag_F[i][band] <<= shift_ov;
- } else {
- ppQmfBufferOutReal_F[i][band] >>= (-shift_ov);
- ppQmfBufferOutImag_F[i][band] >>= (-shift_ov);
- }
+ if (keepStatesSyncedMode == KEEP_STATES_SYNCED_OFF) {
+ int nBands =
+ fMax(0, hQmfTransposer->stopBand - hQmfTransposer->startBand);
+
+ for (i = timeStep * firstSlotOffsset; i < ov_len; i++) {
+ scaleValuesSaturate(&ppQmfBufferOutReal_F[i][hQmfTransposer->startBand],
+ nBands, shift_ov);
+ scaleValuesSaturate(&ppQmfBufferOutImag_F[i][hQmfTransposer->startBand],
+ nBands, shift_ov);
}
- }
- /* shift lpc filterstates */
- for (i = 0; i < timeStep * firstSlotOffsset + LPC_ORDER; i++) {
- for (band = 0; band < (64); band++) {
- if (shift_ov >= 0) {
- lpcFilterStatesReal[i][band] <<= shift_ov;
- lpcFilterStatesImag[i][band] <<= shift_ov;
- } else {
- lpcFilterStatesReal[i][band] >>= (-shift_ov);
- lpcFilterStatesImag[i][band] >>= (-shift_ov);
- }
+ /* shift lpc filterstates */
+ for (i = 0; i < timeStep * firstSlotOffsset + LPC_ORDER; i++) {
+ scaleValuesSaturate(&lpcFilterStatesReal[i][0], (64), shift_ov);
+ scaleValuesSaturate(&lpcFilterStatesImag[i][0], (64), shift_ov);
}
}
}
diff --git a/libSBRdec/src/lpp_tran.cpp b/libSBRdec/src/lpp_tran.cpp
index 113b1de..68a25bf 100644
--- a/libSBRdec/src/lpp_tran.cpp
+++ b/libSBRdec/src/lpp_tran.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -527,7 +527,7 @@ void lppTransposer(
if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) {
resetLPCCoeffs = 1;
} 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))) {
alphar[1] = -alphar[1];
}
@@ -555,7 +555,7 @@ void lppTransposer(
scale)) {
resetLPCCoeffs = 1;
} 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))) {
alphai[1] = -alphai[1];
}
@@ -594,7 +594,7 @@ void lppTransposer(
} else {
INT 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)))
alphar[0] = -alphar[0];
@@ -614,7 +614,7 @@ void lppTransposer(
} else {
INT 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)))
alphai[0] = -alphai[0];
}
@@ -657,7 +657,7 @@ void lppTransposer(
INT scale;
FIXP_DBL result =
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)))) {
k1 = -k1;
@@ -1062,7 +1062,7 @@ void lppTransposerHBE(
if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) {
resetLPCCoeffs = 1;
} 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))) {
alphar[1] = -alphar[1];
}
@@ -1088,7 +1088,7 @@ void lppTransposerHBE(
(result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >> scale)) {
resetLPCCoeffs = 1;
} 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))) {
alphai[1] = -alphai[1];
}
@@ -1117,7 +1117,7 @@ void lppTransposerHBE(
} else {
INT 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)))
alphar[0] = -alphar[0];
@@ -1136,7 +1136,7 @@ void lppTransposerHBE(
} else {
INT 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))) {
alphai[0] = -alphai[0];
}
diff --git a/libSBRdec/src/sbrdec_freq_sca.cpp b/libSBRdec/src/sbrdec_freq_sca.cpp
index e187656..daa3554 100644
--- a/libSBRdec/src/sbrdec_freq_sca.cpp
+++ b/libSBRdec/src/sbrdec_freq_sca.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -765,9 +765,6 @@ resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags) {
sbrdecUpdateLoRes(hFreq->freqBandTable[0], &nBandsLo, hFreq->freqBandTable[1],
nBandsHi);
- hFreq->nSfb[0] = nBandsLo;
- hFreq->nSfb[1] = nBandsHi;
-
/* Check index to freqBandTable[0] */
if (!(nBandsLo > 0) ||
(nBandsLo > (((hHeaderData->numberOfAnalysisBands == 16)
@@ -777,6 +774,9 @@ resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags) {
return SBRDEC_UNSUPPORTED_CONFIG;
}
+ hFreq->nSfb[0] = nBandsLo;
+ hFreq->nSfb[1] = nBandsHi;
+
lsb = hFreq->freqBandTable[0][0];
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 > MAX_NOISE_COEFFS) {
+ return SBRDEC_UNSUPPORTED_CONFIG;
+ }
+
hFreq->nNfb = intTemp;
}
hFreq->nInvfBands = hFreq->nNfb;
- if (hFreq->nNfb > MAX_NOISE_COEFFS) {
- return SBRDEC_UNSUPPORTED_CONFIG;
- }
-
/* Get noise bands */
sbrdecDownSampleLoRes(hFreq->freqBandTableNoise, hFreq->nNfb,
hFreq->freqBandTable[0], nBandsLo);
diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp
index b101a4a..7718695 100644
--- a/libSBRdec/src/sbrdecoder.cpp
+++ b/libSBRdec/src/sbrdecoder.cpp
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------------
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.
1. INTRODUCTION
@@ -961,8 +961,10 @@ SBR_ERROR sbrDecoder_SetParam(HANDLE_SBRDECODER self, const SBRDEC_PARAM param,
/* Set sync state UPSAMPLING for the corresponding slot.
This switches off bitstream parsing until a new header arrives. */
- hSbrHeader->syncState = UPSAMPLING;
- hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE;
+ if (hSbrHeader->syncState != SBR_NOT_INITIALIZED) {
+ hSbrHeader->syncState = UPSAMPLING;
+ hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE;
+ }
}
}
} break;
@@ -1371,7 +1373,9 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
}
if (headerStatus == HEADER_ERROR) {
/* Corrupt SBR info data, do not decode and switch to UPSAMPLING */
- hSbrHeader->syncState = UPSAMPLING;
+ hSbrHeader->syncState = hSbrHeader->syncState > UPSAMPLING
+ ? UPSAMPLING
+ : hSbrHeader->syncState;
fDoDecodeSbrData = 0;
sbrHeaderPresent = 0;
}
@@ -1610,7 +1614,9 @@ static SBR_ERROR sbrDecoder_DecodeElement(
/* No valid SBR payload available, hence switch to upsampling (in all
* headers) */
for (hdrIdx = 0; hdrIdx < ((1) + 1); hdrIdx += 1) {
- self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING;
+ if (self->sbrHeader[elementIndex][hdrIdx].syncState > UPSAMPLING) {
+ self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING;
+ }
}
} else {
/* Move frame pointer to the next slot which is up to be decoded/applied