summaryrefslogtreecommitdiffstats
path: root/fdk-aac/libSACdec/src
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2021-06-01 14:42:00 +0200
committerMatthias P. Braendli <matthias.braendli@mpb.li>2021-06-01 14:42:00 +0200
commite0835d4cbde8e3b61b0c965afcd41f8f4b7ac121 (patch)
treef49619fc806249da71afaf2ac14f99e088d24153 /fdk-aac/libSACdec/src
parent5ad4acef6721a67b8156cd6f7b45ad59849ca09b (diff)
downloadODR-AudioEnc-e0835d4cbde8e3b61b0c965afcd41f8f4b7ac121.tar.gz
ODR-AudioEnc-e0835d4cbde8e3b61b0c965afcd41f8f4b7ac121.tar.bz2
ODR-AudioEnc-e0835d4cbde8e3b61b0c965afcd41f8f4b7ac121.zip
Update fdk to v2.0.2
Diffstat (limited to 'fdk-aac/libSACdec/src')
-rw-r--r--fdk-aac/libSACdec/src/sac_bitdec.cpp32
-rw-r--r--fdk-aac/libSACdec/src/sac_calcM1andM2.h5
-rw-r--r--fdk-aac/libSACdec/src/sac_dec.cpp39
-rw-r--r--fdk-aac/libSACdec/src/sac_dec.h5
-rw-r--r--fdk-aac/libSACdec/src/sac_dec_interface.h8
-rw-r--r--fdk-aac/libSACdec/src/sac_dec_lib.cpp26
-rw-r--r--fdk-aac/libSACdec/src/sac_process.cpp175
-rw-r--r--fdk-aac/libSACdec/src/sac_qmf.cpp4
-rw-r--r--fdk-aac/libSACdec/src/sac_qmf.h4
-rw-r--r--fdk-aac/libSACdec/src/sac_reshapeBBEnv.cpp215
-rw-r--r--fdk-aac/libSACdec/src/sac_rom.h15
-rw-r--r--fdk-aac/libSACdec/src/sac_stp.cpp155
-rw-r--r--fdk-aac/libSACdec/src/sac_tsd.cpp28
13 files changed, 366 insertions, 345 deletions
diff --git a/fdk-aac/libSACdec/src/sac_bitdec.cpp b/fdk-aac/libSACdec/src/sac_bitdec.cpp
index 062eb1c..708ddf1 100644
--- a/fdk-aac/libSACdec/src/sac_bitdec.cpp
+++ b/fdk-aac/libSACdec/src/sac_bitdec.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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -1555,22 +1555,20 @@ static SACDEC_ERROR mapIndexData(
/* Interpolate */
i1 = 0;
for (i = 0; i < numParameterSets; i++) {
- int xi, i2, x1, x2;
-
if (aInterpolate[i] != 1) {
i1 = i;
- }
- i2 = i;
- while (aInterpolate[i2] == 1) {
- i2++;
- if (i2 >= MAX_PARAMETER_SETS) return MPS_WRONG_PARAMETERSETS;
- }
- x1 = paramSlot[i1];
- xi = paramSlot[i];
- x2 = paramSlot[i2];
+ } else {
+ int xi, i2, x1, x2;
- if (aInterpolate[i] == 1) {
+ for (i2 = i; i2 < numParameterSets; i2++) {
+ if (aInterpolate[i2] != 1) break;
+ }
if (i2 >= numParameterSets) return MPS_WRONG_PARAMETERSETS;
+
+ x1 = paramSlot[i1];
+ xi = paramSlot[i];
+ x2 = paramSlot[i2];
+
for (band = startBand; band < stopBand; band++) {
int yi, y1, y2;
y1 = outputIdxData[xttIdx][i1][band];
@@ -1589,9 +1587,9 @@ static SACDEC_ERROR mapIndexData(
for (ps = 0; ps < numParameterSets; ps++) {
if (quantMode && (paramType == t_CLD)) {
if (pOttVsTotDbIn == 0) return MPS_WRONG_OTT;
- if ((pOttVsTotDb1 == 0) && (ottVsTotDbMode == ottVsTotDb1Activ))
+ if ((pOttVsTotDb1 == 0) && (ottVsTotDbMode & ottVsTotDb1Activ))
return MPS_WRONG_OTT;
- if ((pOttVsTotDb2 == 0) && (ottVsTotDbMode == ottVsTotDb2Activ))
+ if ((pOttVsTotDb2 == 0) && (ottVsTotDbMode & ottVsTotDb2Activ))
return MPS_WRONG_OTT;
for (pb = startBand; pb < stopBand; pb++) {
@@ -1613,6 +1611,10 @@ static SACDEC_ERROR mapIndexData(
} /* for( i = 0 ; i < numParameterSets; i++ ) */
if (extendFrame) {
+ if (paramType == t_IPD) {
+ llData->bsQuantCoarseXXX[numParameterSets] =
+ llData->bsQuantCoarseXXX[numParameterSets - 1];
+ }
for (band = startBand; band < stopBand; band++) {
outputDataIdx[xttIdx][numParameterSets][band] =
outputDataIdx[xttIdx][numParameterSets - 1][band];
diff --git a/fdk-aac/libSACdec/src/sac_calcM1andM2.h b/fdk-aac/libSACdec/src/sac_calcM1andM2.h
index 996238d..cefc4bb 100644
--- a/fdk-aac/libSACdec/src/sac_calcM1andM2.h
+++ b/fdk-aac/libSACdec/src/sac_calcM1andM2.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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -117,6 +117,9 @@ amm-info@iis.fraunhofer.de
/* Scaling of spectral data after applying M2 matrix, but only for binaural
upmix type Scaling is compensated later in synthesis qmf filterbank */
#define SCALE_DATA_APPLY_M2 (1)
+/* Applying M2 parameter in combination with phase coding needs 2 bits headroom
+ * because up to a maximum of 4 spectral values can be added for USAC */
+#define SCALE_DATA_APPLY_M2_PC (2)
SACDEC_ERROR initM1andM2(spatialDec* self, int initStatesFlag,
int configChanged);
diff --git a/fdk-aac/libSACdec/src/sac_dec.cpp b/fdk-aac/libSACdec/src/sac_dec.cpp
index 3f55a7d..a7b50df 100644
--- a/fdk-aac/libSACdec/src/sac_dec.cpp
+++ b/fdk-aac/libSACdec/src/sac_dec.cpp
@@ -766,7 +766,7 @@ SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame,
/* output scaling */
for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) {
- int outputScale = 0, outputGain_e = 0, scale = 0;
+ int outputScale = 0, outputGain_e = 0, scale = -(8) + (1);
FIXP_DBL outputGain_m = getChGain(self, nCh, &outputGain_e);
if (!isTwoChMode(self->upmixType) && !bypassMode) {
@@ -775,7 +775,7 @@ SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame,
synthesis qmf */
}
- scale = outputScale;
+ scale += outputScale;
qmfChangeOutScalefactor(&self->pQmfDomain->QmfDomainOut[nCh].fb, scale);
qmfChangeOutGain(&self->pQmfDomain->QmfDomainOut[nCh].fb, outputGain_m,
@@ -1223,18 +1223,24 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
!(self->stereoConfigIndex == 3)) {
for (i = 0; i < self->qmfBands; i++) {
self_qmfResidualReal__FDK_0_0[i] =
- fMult(self_qmfResidualReal__FDK_0_0[i] << 1,
+ fMult(scaleValueSaturate(self_qmfResidualReal__FDK_0_0[i],
+ 1 + self->sacInDataHeadroom - (1)),
self->clipProtectGain__FDK);
self_qmfResidualImag__FDK_0_0[i] =
- fMult(self_qmfResidualImag__FDK_0_0[i] << 1,
+ fMult(scaleValueSaturate(self_qmfResidualImag__FDK_0_0[i],
+ 1 + self->sacInDataHeadroom - (1)),
self->clipProtectGain__FDK);
}
} else {
for (i = 0; i < self->qmfBands; i++) {
- self_qmfResidualReal__FDK_0_0[i] = fMult(
- self_qmfResidualReal__FDK_0_0[i], self->clipProtectGain__FDK);
- self_qmfResidualImag__FDK_0_0[i] = fMult(
- self_qmfResidualImag__FDK_0_0[i], self->clipProtectGain__FDK);
+ self_qmfResidualReal__FDK_0_0[i] =
+ fMult(scaleValueSaturate(self_qmfResidualReal__FDK_0_0[i],
+ self->sacInDataHeadroom - (1)),
+ self->clipProtectGain__FDK);
+ self_qmfResidualImag__FDK_0_0[i] =
+ fMult(scaleValueSaturate(self_qmfResidualImag__FDK_0_0[i],
+ self->sacInDataHeadroom - (1)),
+ self->clipProtectGain__FDK);
}
}
}
@@ -1317,10 +1323,12 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
if ((self->tempShapeConfig == 1) && (!isTwoChMode(self->upmixType))) {
for (ch = 0; ch < self->numOutputChannels; ch++) {
for (hyb = 0; hyb < self->tp_hybBandBorder; hyb++) {
- self->hybOutputRealDry__FDK[ch][hyb] +=
- self->hybOutputRealWet__FDK[ch][hyb];
- self->hybOutputImagDry__FDK[ch][hyb] +=
- self->hybOutputImagWet__FDK[ch][hyb];
+ self->hybOutputRealDry__FDK[ch][hyb] =
+ fAddSaturate(self->hybOutputRealDry__FDK[ch][hyb],
+ self->hybOutputRealWet__FDK[ch][hyb]);
+ self->hybOutputImagDry__FDK[ch][hyb] =
+ fAddSaturate(self->hybOutputImagDry__FDK[ch][hyb],
+ self->hybOutputImagWet__FDK[ch][hyb]);
} /* loop hyb */
} /* loop ch */
err = subbandTPApply(
@@ -1341,11 +1349,11 @@ static SACDEC_ERROR SpatialDecApplyParameterSets(
FIXP_DBL *RESTRICT pRealWet = self->hybOutputRealWet__FDK[ch];
FIXP_DBL *RESTRICT pImagWet = self->hybOutputImagWet__FDK[ch];
for (hyb = 0; hyb < nHybBands; hyb++) {
- pRealDry[hyb] += pRealWet[hyb];
- pImagDry[hyb] += pImagWet[hyb];
+ pRealDry[hyb] = fAddSaturate(pRealDry[hyb], pRealWet[hyb]);
+ pImagDry[hyb] = fAddSaturate(pImagDry[hyb], pImagWet[hyb]);
} /* loop hyb */
for (; hyb < self->hybridBands; hyb++) {
- pRealDry[hyb] += pRealWet[hyb];
+ pRealDry[hyb] = fAddSaturate(pRealDry[hyb], pRealWet[hyb]);
} /* loop hyb */
} /* loop ch */
} /* ( self->tempShapeConfig == 1 ) || ( self->tempShapeConfig == 2 ) */
@@ -1414,6 +1422,7 @@ SACDEC_ERROR SpatialDecApplyFrame(
FDK_ASSERT(self != NULL);
FDK_ASSERT(pControlFlags != NULL);
FDK_ASSERT(pcmOutBuf != NULL);
+ FDK_ASSERT(self->sacInDataHeadroom >= (1));
self->errInt = err; /* Init internal error */
diff --git a/fdk-aac/libSACdec/src/sac_dec.h b/fdk-aac/libSACdec/src/sac_dec.h
index 992acad..1c3df71 100644
--- a/fdk-aac/libSACdec/src/sac_dec.h
+++ b/fdk-aac/libSACdec/src/sac_dec.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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -523,6 +523,9 @@ struct spatialDec_struct {
new frame after SSC change (aka
decodeAfterConfigHasChangedFlag). */
SpatialDecConcealmentInfo concealInfo;
+
+ INT sacInDataHeadroom; /* Headroom of the SAC input time signal to prevent
+ clipping */
};
#define SACDEC_SYNTAX_MPS 1
diff --git a/fdk-aac/libSACdec/src/sac_dec_interface.h b/fdk-aac/libSACdec/src/sac_dec_interface.h
index a2eea92..05a9a75 100644
--- a/fdk-aac/libSACdec/src/sac_dec_interface.h
+++ b/fdk-aac/libSACdec/src/sac_dec_interface.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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -249,10 +249,10 @@ typedef struct {
} MEM_REQUIREMENTS;
-#define PCM_MPS INT_PCM
-#define PCM_MPSF FIXP_PCM
+#define PCM_MPS LONG
+#define PCM_MPSF FIXP_DBL
-#define FIXP_DBL2PCM_MPS(x) ((INT_PCM)FX_DBL2FX_PCM(x))
+#define FIXP_DBL2PCM_MPS(x) ((LONG)(x))
/* exposed functions (library interface) */
diff --git a/fdk-aac/libSACdec/src/sac_dec_lib.cpp b/fdk-aac/libSACdec/src/sac_dec_lib.cpp
index bf6dedf..57446f8 100644
--- a/fdk-aac/libSACdec/src/sac_dec_lib.cpp
+++ b/fdk-aac/libSACdec/src/sac_dec_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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -1507,15 +1507,17 @@ bail:
}
int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
- INT_PCM *input, PCM_MPS *pTimeData,
+ PCM_MPS *input, PCM_MPS *pTimeData,
const int timeDataSize, int timeDataFrameSize,
int *nChannels, int *frameSize, int sampleRate,
AUDIO_OBJECT_TYPE coreCodec,
AUDIO_CHANNEL_TYPE channelType[],
UCHAR channelIndices[],
- const FDK_channelMapDescr *const mapDescr) {
+ const FDK_channelMapDescr *const mapDescr,
+ const INT inDataHeadroom, INT *outDataHeadroom) {
SACDEC_ERROR err = MPS_OK;
PCM_MPS *pTimeOut = pTimeData;
+ PCM_MPS *TDinput = NULL;
UINT initControlFlags = 0, controlFlags = 0;
int timeDataRequiredSize = 0;
int newData;
@@ -1534,6 +1536,9 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
return MPS_NOTOK;
}
+ pMpegSurroundDecoder->pSpatialDec->sacInDataHeadroom = inDataHeadroom;
+ *outDataHeadroom = (INT)(8);
+
pMpegSurroundDecoder->pSpatialDec->pConfigCurrent =
&pMpegSurroundDecoder
->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode];
@@ -1682,8 +1687,7 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
(timeDataFrameSize *
pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsSynthesis) /
pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsAnalysis;
- pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput =
- pTimeData + timeDataFrameSizeOut - timeDataFrameSize;
+ TDinput = pTimeData + timeDataFrameSizeOut - timeDataFrameSize;
for (int i = *nChannels - 1; i >= 0; i--) {
FDKmemmove(pTimeData + (i + 1) * timeDataFrameSizeOut - timeDataFrameSize,
pTimeData + timeDataFrameSize * i,
@@ -1694,8 +1698,8 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
} else {
if (pMpegSurroundDecoder->mpegSurroundUseTimeInterface) {
FDKmemcpy(input, pTimeData,
- sizeof(INT_PCM) * (*nChannels) * (*frameSize));
- pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput = input;
+ sizeof(PCM_MPS) * (*nChannels) * (*frameSize));
+ TDinput = input;
}
}
@@ -1707,8 +1711,8 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder,
&pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode],
pMpegSurroundDecoder->mpegSurroundUseTimeInterface ? INPUTMODE_TIME
: INPUTMODE_QMF_SBR,
- pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput, NULL, NULL,
- pTimeOut, *frameSize, &controlFlags, *nChannels, mapDescr);
+ TDinput, NULL, NULL, pTimeOut, *frameSize, &controlFlags, *nChannels,
+ mapDescr);
*nChannels = pMpegSurroundDecoder->pSpatialDec->numOutputChannelsAT;
if (err !=
@@ -1781,7 +1785,7 @@ void mpegSurroundDecoder_Close(CMpegSurroundDecoder *pMpegSurroundDecoder) {
}
#define SACDEC_VL0 2
-#define SACDEC_VL1 0
+#define SACDEC_VL1 1
#define SACDEC_VL2 0
int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) {
@@ -1800,7 +1804,7 @@ int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) {
info += i;
info->module_id = FDK_MPSDEC;
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
info->build_date = "";
info->build_time = "";
#else
diff --git a/fdk-aac/libSACdec/src/sac_process.cpp b/fdk-aac/libSACdec/src/sac_process.cpp
index 56c72ad..22091a9 100644
--- a/fdk-aac/libSACdec/src/sac_process.cpp
+++ b/fdk-aac/libSACdec/src/sac_process.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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -113,6 +113,8 @@ amm-info@iis.fraunhofer.de
#include "FDK_trigFcts.h"
#include "FDK_decorrelate.h"
+#define SAC_DEC_APPLY_M2_SCALE(spec, s) ((spec) >> (-(s)))
+
/**
* \brief Linear interpolation between two parameter values.
* a*alpha + b*(1-alpha)
@@ -185,8 +187,12 @@ SACDEC_ERROR SpatialDecQMFAnalysis(spatialDec *self, const PCM_MPS *inData,
if (!isTwoChMode(self->upmixType) && !bypassMode) {
int i;
for (i = 0; i < self->qmfBands; i++) {
- qmfReal[ch][i] = fMult(qmfReal[ch][i], self->clipProtectGain__FDK);
- qmfImag[ch][i] = fMult(qmfImag[ch][i], self->clipProtectGain__FDK);
+ qmfReal[ch][i] = fMult(
+ scaleValueSaturate(qmfReal[ch][i], self->sacInDataHeadroom - (1)),
+ self->clipProtectGain__FDK);
+ qmfImag[ch][i] = fMult(
+ scaleValueSaturate(qmfImag[ch][i], self->sacInDataHeadroom - (1)),
+ self->clipProtectGain__FDK);
}
}
}
@@ -214,16 +220,17 @@ SACDEC_ERROR SpatialDecFeedQMF(spatialDec *self, FIXP_DBL **qmfInDataReal,
/* Write Input data to pQmfRealAnalysis. */
if (self->bShareDelayWithSBR) {
- FDK_QmfDomain_GetSlot(
- &self->pQmfDomain->QmfDomainIn[ch], ts + HYBRID_FILTER_DELAY, 0,
- MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis, pQmfImagAnalysis, 15);
+ FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch],
+ ts + HYBRID_FILTER_DELAY, 0,
+ MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis,
+ pQmfImagAnalysis, 15 + (1));
FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts,
MAX_QMF_BANDS_TO_HYBRID, self->qmfBands,
- pQmfRealAnalysis, pQmfImagAnalysis, 15);
+ pQmfRealAnalysis, pQmfImagAnalysis, 15 + (1));
} else {
FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts, 0,
self->qmfBands, pQmfRealAnalysis,
- pQmfImagAnalysis, 15);
+ pQmfImagAnalysis, 15 + (1));
}
if (ts == self->pQmfDomain->globalConf.nQmfTimeSlots - 1) {
/* Is currently also needed in case we dont have any overlap. We need to
@@ -499,8 +506,8 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
for (pb = 0, qs = 3; pb < 2; pb++) {
INT s;
FIXP_DBL maxVal;
- FIXP_SGL mReal1;
- FIXP_SGL mReal0, mImag0;
+ FIXP_DBL mReal1;
+ FIXP_DBL mReal0, mImag0;
FIXP_DBL iReal0, iImag0, iReal1;
iReal0 = interpolateParameter(alpha, MReal0[pb], MRealPrev0[pb]);
@@ -513,9 +520,9 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
s = fMax(CntLeadingZeros(maxVal) - 1, 0);
s = fMin(s, scale_param_m2);
- mReal0 = FX_DBL2FX_SGL(iReal0 << s);
- mImag0 = FX_DBL2FX_SGL(iImag0 << s);
- mReal1 = FX_DBL2FX_SGL(iReal1 << s);
+ mReal0 = iReal0 << s;
+ mImag0 = iImag0 << s;
+ mReal1 = iReal1 << s;
s = scale_param_m2 - s;
@@ -634,8 +641,7 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
}
if (self->phaseCoding == 3) {
- /* + SCALE_DATA_APPLY_M2 to compensate for Div2 below ?! */
- scale_param_m2 = SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2;
+ scale_param_m2 = -(SCALE_DATA_APPLY_M2_PC - 1);
}
for (row = 0; row < self->numM2rows; row++) {
@@ -686,10 +692,10 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
} else { /* isBinauralMode(self->upmixType) */
for (qs = 0; qs < complexHybBands; qs++) {
- pHybOutRealDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
- << (scale_param_m2);
- pHybOutImagDry[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
- << (scale_param_m2);
+ pHybOutRealDry[qs] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
+ pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
}
M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col],
@@ -697,27 +703,27 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
self->kernels_width, alpha, complexParBands);
/* direct signals sign is -1 for qs = 0,2 */
- pHybOutRealDry[0] += fMultDiv2(pWImag[0], pKernel[0])
- << (scale_param_m2);
- pHybOutImagDry[0] -= fMultDiv2(pWReal[0], pKernel[0])
- << (scale_param_m2);
+ pHybOutRealDry[0] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
+ pHybOutImagDry[0] -= SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
- pHybOutRealDry[2] += fMultDiv2(pWImag[2], pKernel[2])
- << (scale_param_m2);
- pHybOutImagDry[2] -= fMultDiv2(pWReal[2], pKernel[2])
- << (scale_param_m2);
+ pHybOutRealDry[2] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
+ pHybOutImagDry[2] -= SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
/* direct signals sign is +1 for qs = 1,3,4,5,...,complexHybBands */
- pHybOutRealDry[1] -= fMultDiv2(pWImag[1], pKernel[1])
- << (scale_param_m2);
- pHybOutImagDry[1] += fMultDiv2(pWReal[1], pKernel[1])
- << (scale_param_m2);
+ pHybOutRealDry[1] -= SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
+ pHybOutImagDry[1] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
for (qs = 3; qs < complexHybBands; qs++) {
- pHybOutRealDry[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
- << (scale_param_m2);
- pHybOutImagDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
- << (scale_param_m2);
+ pHybOutRealDry[qs] -= SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
+ pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
}
} /* self->upmixType */
} /* if (activParamBands) */
@@ -770,17 +776,17 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
FIXP_DBL *RESTRICT pHybOutImag;
for (qs = 0; qs < resHybIndex; qs++) {
- pHybOutRealDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
- << (scale_param_m2);
- pHybOutImagDry[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
- << (scale_param_m2);
+ pHybOutRealDry[qs] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
+ pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
}
/* decor signals */
for (; qs < complexHybBands; qs++) {
- pHybOutRealWet[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
- << (scale_param_m2);
- pHybOutImagWet[qs] += fMultDiv2(pWImag[qs], pKernel[qs])
- << (scale_param_m2);
+ pHybOutRealWet[qs] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
+ pHybOutImagWet[qs] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
}
M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col],
@@ -790,20 +796,20 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
/* direct signals sign is -1 for qs = 0,2 */
/* direct signals sign is +1 for qs = 1,3.. */
if (toolsDisabled) {
- pHybOutRealDry[0] += fMultDiv2(pWImag[0], pKernel[0])
- << (scale_param_m2);
- pHybOutImagDry[0] -= fMultDiv2(pWReal[0], pKernel[0])
- << (scale_param_m2);
-
- pHybOutRealDry[1] -= fMultDiv2(pWImag[1], pKernel[1])
- << (scale_param_m2);
- pHybOutImagDry[1] += fMultDiv2(pWReal[1], pKernel[1])
- << (scale_param_m2);
-
- pHybOutRealDry[2] += fMultDiv2(pWImag[2], pKernel[2])
- << (scale_param_m2);
- pHybOutImagDry[2] -= fMultDiv2(pWReal[2], pKernel[2])
- << (scale_param_m2);
+ pHybOutRealDry[0] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
+ pHybOutImagDry[0] -= SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
+
+ pHybOutRealDry[1] -= SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
+ pHybOutImagDry[1] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
+
+ pHybOutRealDry[2] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
+ pHybOutImagDry[2] -= SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
} else {
pHybOutReal = &pHybOutRealDry[0];
pHybOutImag = &pHybOutImagDry[0];
@@ -811,46 +817,60 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
pHybOutReal = &pHybOutRealWet[0];
pHybOutImag = &pHybOutImagWet[0];
}
- pHybOutReal[0] += fMultDiv2(pWImag[0], pKernel[0])
- << (scale_param_m2);
- pHybOutImag[0] -= fMultDiv2(pWReal[0], pKernel[0])
- << (scale_param_m2);
+ pHybOutReal[0] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
+ pHybOutImag[0] -= SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
if (1 == resHybIndex) {
pHybOutReal = &pHybOutRealWet[0];
pHybOutImag = &pHybOutImagWet[0];
}
- pHybOutReal[1] -= fMultDiv2(pWImag[1], pKernel[1])
- << (scale_param_m2);
- pHybOutImag[1] += fMultDiv2(pWReal[1], pKernel[1])
- << (scale_param_m2);
+ pHybOutReal[1] -= SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
+ pHybOutImag[1] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
if (2 == resHybIndex) {
pHybOutReal = &pHybOutRealWet[0];
pHybOutImag = &pHybOutImagWet[0];
}
- pHybOutReal[2] += fMultDiv2(pWImag[2], pKernel[2])
- << (scale_param_m2);
- pHybOutImag[2] -= fMultDiv2(pWReal[2], pKernel[2])
- << (scale_param_m2);
+ pHybOutReal[2] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
+ pHybOutImag[2] -= SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
}
for (qs = 3; qs < resHybIndex; qs++) {
- pHybOutRealDry[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
- << (scale_param_m2);
- pHybOutImagDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
- << (scale_param_m2);
+ pHybOutRealDry[qs] -= SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
+ pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
}
/* decor signals */
for (; qs < complexHybBands; qs++) {
- pHybOutRealWet[qs] -= fMultDiv2(pWImag[qs], pKernel[qs])
- << (scale_param_m2);
- pHybOutImagWet[qs] += fMultDiv2(pWReal[qs], pKernel[qs])
- << (scale_param_m2);
+ pHybOutRealWet[qs] -= SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
+ pHybOutImagWet[qs] += SAC_DEC_APPLY_M2_SCALE(
+ fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
}
} /* self->upmixType */
} /* if (activParamBands) { */
} /* self->numVChannels */
+
+ if (self->phaseCoding == 3) {
+ scaleValuesSaturate(pHybOutRealDry, complexHybBands,
+ SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
+ scaleValuesSaturate(pHybOutImagDry, complexHybBands,
+ SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
+
+ if (!toolsDisabled) {
+ scaleValuesSaturate(pHybOutRealWet, complexHybBands,
+ SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
+ scaleValuesSaturate(pHybOutImagWet, complexHybBands,
+ SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
+ }
+ }
}
C_ALLOC_SCRATCH_END(pKernel, FIXP_SGL, MAX_HYBRID_BANDS);
@@ -919,6 +939,7 @@ SACDEC_ERROR SpatialDecSynthesis(spatialDec *self, const INT ts,
self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -=
self->clipProtectGainSF__FDK;
+ self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -= (1);
} else {
/* Call the QMF synthesis for dry. */
err = CalculateSpaceSynthesisQmf(&self->pQmfDomain->QmfDomainOut[outCh],
diff --git a/fdk-aac/libSACdec/src/sac_qmf.cpp b/fdk-aac/libSACdec/src/sac_qmf.cpp
index a075490..fd7599d 100644
--- a/fdk-aac/libSACdec/src/sac_qmf.cpp
+++ b/fdk-aac/libSACdec/src/sac_qmf.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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de
SACDEC_ERROR CalculateSpaceSynthesisQmf(
const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr,
- const FIXP_DBL *Si, const INT stride, INT_PCM *timeSig) {
+ const FIXP_DBL *Si, const INT stride, PCM_MPS *timeSig) {
SACDEC_ERROR err = MPS_OK;
if (hQmfDomainOutCh == NULL) {
diff --git a/fdk-aac/libSACdec/src/sac_qmf.h b/fdk-aac/libSACdec/src/sac_qmf.h
index d1dc837..5cd573e 100644
--- a/fdk-aac/libSACdec/src/sac_qmf.h
+++ b/fdk-aac/libSACdec/src/sac_qmf.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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -124,7 +124,7 @@ amm-info@iis.fraunhofer.de
*/
SACDEC_ERROR CalculateSpaceSynthesisQmf(
const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr,
- const FIXP_DBL *Si, const INT stride, INT_PCM *timeSig);
+ const FIXP_DBL *Si, const INT stride, PCM_MPS *timeSig);
/**
* \brief Convert audio input data to qmf representation.
diff --git a/fdk-aac/libSACdec/src/sac_reshapeBBEnv.cpp b/fdk-aac/libSACdec/src/sac_reshapeBBEnv.cpp
index 87c0ac6..272d009 100644
--- a/fdk-aac/libSACdec/src/sac_reshapeBBEnv.cpp
+++ b/fdk-aac/libSACdec/src/sac_reshapeBBEnv.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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -162,75 +162,59 @@ static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
FIXP_DBL nrg;
/* qs = 12, 13, 14 */
- slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
- slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
- slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
+ slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
+ slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
+ slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 15 */
- slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
+ slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 16, 17 */
- nrg = ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
- slotNrg[4] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
+ nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
+ slotNrg[4] =
+ nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 18, 19, 20 */
- nrg = ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
- nrg += ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
- slotNrg[5] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
+ nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
+ nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
+ slotNrg[5] =
+ nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 21, 22 */
- nrg = ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
- slotNrg[6] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
+ nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
+ slotNrg[6] =
+ nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 23, 24 */
if (hybBands > 23) {
- slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
- slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
+ slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
+ slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 25, 26, 29, 28, 29 */
- nrg = ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
- nrg += ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
- nrg += ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
- nrg += ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
- slotNrg[7] = nrg + ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
+ nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
+ nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
+ nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
+ nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
+ slotNrg[7] =
+ nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
/* qs = 30 ... min(41,hybBands-1) */
- nrg = ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
+ nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
for (qs = 31; qs < hybBands; qs++) {
- nrg += ((fPow2Div2((*pReal++) << maxValSF) +
- fPow2Div2((*pImag++) << maxValSF)) >>
- (SF_FACTOR_SLOT - 1));
+ nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
+ (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
}
slotNrg[8] = nrg;
} else {
@@ -239,49 +223,22 @@ static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
}
}
-static inline INT getMaxValDmx(FIXP_DBL *RESTRICT pReal,
- FIXP_DBL *RESTRICT pImag, INT cplxBands,
- INT hybBands) {
- INT qs, clz;
- FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
-
- for (qs = 12; qs < cplxBands; qs++) {
- maxVal |= fAbs(pReal[qs]);
- maxVal |= fAbs(pImag[qs]);
- }
- for (; qs < hybBands; qs++) {
- maxVal |= fAbs(pReal[qs]);
- }
-
- clz = fixMax(0, CntLeadingZeros(maxVal) - 1);
-
- return (clz);
-}
-
-static inline INT getMaxValDryWet(FIXP_DBL *RESTRICT pReal,
- FIXP_DBL *RESTRICT pImag,
- FIXP_DBL *RESTRICT pHybOutputRealDry,
- FIXP_DBL *RESTRICT pHybOutputImagDry,
- FIXP_DBL *RESTRICT pHybOutputRealWet,
- FIXP_DBL *RESTRICT pHybOutputImagWet,
- INT cplxBands, INT hybBands) {
- INT qs, clz;
- FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
+static inline void combineDryWet(FIXP_DBL *RESTRICT pReal,
+ FIXP_DBL *RESTRICT pImag,
+ FIXP_DBL *RESTRICT pHybOutputRealDry,
+ FIXP_DBL *RESTRICT pHybOutputImagDry,
+ FIXP_DBL *RESTRICT pHybOutputRealWet,
+ FIXP_DBL *RESTRICT pHybOutputImagWet,
+ INT cplxBands, INT hybBands) {
+ INT qs;
for (qs = 12; qs < cplxBands; qs++) {
- pReal[qs] = pHybOutputRealDry[qs] + pHybOutputRealWet[qs];
- maxVal |= fAbs(pReal[qs]);
- pImag[qs] = pHybOutputImagDry[qs] + pHybOutputImagWet[qs];
- maxVal |= fAbs(pImag[qs]);
+ pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
+ pImag[qs] = (pHybOutputImagDry[qs] >> 1) + (pHybOutputImagWet[qs] >> 1);
}
for (; qs < hybBands; qs++) {
- pReal[qs] = pHybOutputRealDry[qs] + pHybOutputRealWet[qs];
- maxVal |= fAbs(pReal[qs]);
+ pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
}
-
- clz = fixMax(0, CntLeadingZeros(maxVal) - 1);
-
- return (clz);
}
static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry,
@@ -296,17 +253,17 @@ static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry,
dry = wet = FL2FXCONST_DBL(0.0f);
for (qs = 0; qs < cplxBands; qs++) {
- dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs]) +
- fPow2Div2(pHybOutputImagDry[qs]));
- wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs]) +
- fPow2Div2(pHybOutputImagWet[qs]));
+ dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)) +
+ fPow2Div2(pHybOutputImagDry[qs] << (1)));
+ wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)) +
+ fPow2Div2(pHybOutputImagWet[qs] << (1)));
}
for (; qs < hybBands; qs++) {
- dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs]));
- wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs]));
+ dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)));
+ wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)));
}
- *slotAmp_dry = dry;
- *slotAmp_wet = wet;
+ *slotAmp_dry = dry >> (2 * (1));
+ *slotAmp_wet = wet >> (2 * (1));
}
#if defined(__aarch64__)
@@ -327,11 +284,14 @@ shapeBBEnv(FIXP_DBL *pHybOutputRealDry, FIXP_DBL *pHybOutputImagDry,
}
} else {
for (qs = 0; qs < cplxBands; qs++) {
- pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac) << scale;
- pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac) << scale;
+ pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
+ fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
+ pHybOutputImagDry[qs] = SATURATE_LEFT_SHIFT(
+ fMultDiv2(pHybOutputImagDry[qs], dryFac), scale, DFRACT_BITS);
}
for (; qs < hybBands; qs++) {
- pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac) << scale;
+ pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
+ fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
}
}
}
@@ -367,7 +327,7 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
INT shapeActiv = 1;
INT hybBands = fixMin(42, self->hybridBands);
- INT staticScale = self->staticDecScale;
+ INT staticScale = self->staticDecScale + (1);
INT cplxBands;
cplxBands = fixMin(42, self->hybridBands);
@@ -386,15 +346,18 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
prevChOffs = ch;
pReal = pScratchBuffer;
pImag = pScratchBuffer + 42;
- clz = getMaxValDryWet(
- pReal, pImag, self->hybOutputRealDry__FDK[ch],
- self->hybOutputImagDry__FDK[ch], self->hybOutputRealWet__FDK[ch],
- self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
+ combineDryWet(pReal, pImag, self->hybOutputRealDry__FDK[ch],
+ self->hybOutputImagDry__FDK[ch],
+ self->hybOutputRealWet__FDK[ch],
+ self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
+ clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
+ getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
} else {
prevChOffs = ch + self->numOutputChannels;
pReal = self->hybInputReal__FDK[ch];
pImag = self->hybInputImag__FDK[ch];
- clz = getMaxValDmx(pReal, pImag, cplxBands, hybBands);
+ clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
+ getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
}
partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs];
@@ -411,8 +374,10 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
SF_FACTOR_SLOT */
}
- slotNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT;
- frameNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT;
+ slotNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
+ SF_FACTOR_SLOT;
+ frameNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
+ SF_FACTOR_SLOT;
partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1,
pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 1);
@@ -652,14 +617,16 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
fixMax(3, fixMax(dryFacSF, slotAmpSF)); /* scale is at least with 3
bits to avoid overflows
when calculating dryFac */
- dryFac = dryFac >> (scale - dryFacSF);
- slotAmp_ratio = slotAmp_ratio >> (scale - slotAmpSF);
+ dryFac = dryFac >> fixMin(scale - dryFacSF, DFRACT_BITS - 1);
+ slotAmp_ratio =
+ slotAmp_ratio >> fixMin(scale - slotAmpSF, DFRACT_BITS - 1);
/* limit dryFac */
dryFac = fixMax(
FL2FXCONST_DBL(0.25f) >> (INT)fixMin(2 * scale, DFRACT_BITS - 1),
- fMult(dryFac, slotAmp_ratio) - (slotAmp_ratio >> scale) +
- (dryFac >> scale));
+ fMult(dryFac, slotAmp_ratio) -
+ (slotAmp_ratio >> fixMin(scale, DFRACT_BITS - 1)) +
+ (dryFac >> fixMin(scale, DFRACT_BITS - 1)));
dryFac = fixMin(
FL2FXCONST_DBL(0.50f) >> (INT)fixMin(2 * scale - 3, DFRACT_BITS - 1),
dryFac); /* reduce shift bits by 3, because upper
@@ -673,8 +640,8 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
/* shaping */
shapeBBEnv(&self->hybOutputRealDry__FDK[ch][6],
- &self->hybOutputImagDry__FDK[ch][6], dryFac, scale, cplxBands,
- hybBands);
+ &self->hybOutputImagDry__FDK[ch][6], dryFac,
+ fixMin(scale, DFRACT_BITS - 1), cplxBands, hybBands);
}
}
}
diff --git a/fdk-aac/libSACdec/src/sac_rom.h b/fdk-aac/libSACdec/src/sac_rom.h
index 38f17f2..d317856 100644
--- a/fdk-aac/libSACdec/src/sac_rom.h
+++ b/fdk-aac/libSACdec/src/sac_rom.h
@@ -111,21 +111,12 @@ amm-info@iis.fraunhofer.de
#include "machine_type.h"
/* Global ROM table data type: */
-#ifndef ARCH_PREFER_MULT_32x32
-#define FIXP_CFG FIXP_SGL
-#define FX_CFG2FX_DBL FX_SGL2FX_DBL
-#define FX_CFG2FX_SGL
-#define CFG(a) (FX_DBL2FXCONST_SGL(a))
-#define FL2FXCONST_CFG FL2FXCONST_SGL
-#define FX_DBL2FX_CFG(x) FX_DBL2FX_SGL((FIXP_DBL)(x))
-#else
#define FIXP_CFG FIXP_DBL
#define FX_CFG2FX_DBL
#define FX_CFG2FX_SGL FX_DBL2FX_SGL
#define CFG(a) FIXP_DBL(a)
#define FL2FXCONST_CFG FL2FXCONST_DBL
#define FX_DBL2FX_CFG(x) ((FIXP_DBL)(x))
-#endif
/* others */
#define SCALE_INV_ICC (2)
@@ -133,15 +124,9 @@ amm-info@iis.fraunhofer.de
#define QCC_SCALE 1
#define M1M2_DATA FIXP_DBL
-#ifndef ARCH_PREFER_MULT_32x32
-#define M1M2_CDATA FIXP_SGL
-#define M1M2_CDATA2FX_DBL(a) FX_SGL2FX_DBL(a)
-#define FX_DBL2M1M2_CDATA(a) FX_DBL2FX_SGL(a)
-#else
#define M1M2_CDATA FIXP_DBL
#define M1M2_CDATA2FX_DBL(a) (a)
#define FX_DBL2M1M2_CDATA(a) (a)
-#endif
#define CLIP_PROTECT_GAIN_0(x) FL2FXCONST_CFG(((x) / (float)(1 << 0)))
#define CLIP_PROTECT_GAIN_1(x) FL2FXCONST_CFG(((x) / (float)(1 << 1)))
diff --git a/fdk-aac/libSACdec/src/sac_stp.cpp b/fdk-aac/libSACdec/src/sac_stp.cpp
index 818e9df..bb66277 100644
--- a/fdk-aac/libSACdec/src/sac_stp.cpp
+++ b/fdk-aac/libSACdec/src/sac_stp.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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -106,6 +106,8 @@ amm-info@iis.fraunhofer.de
#include "FDK_matrixCalloc.h"
#include "sac_rom.h"
+#define SF_FREQ_DOMAIN_HEADROOM (2 * (1))
+
#define BP_GF_START 6
#define BP_GF_SIZE 25
#define HP_SIZE 9
@@ -114,6 +116,16 @@ amm-info@iis.fraunhofer.de
#define SF_WET 5
#define SF_DRY \
3 /* SF_DRY == 2 would produce good conformance test results as well */
+#define SF_DRY_NRG \
+ (4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \
+ i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \
+ calculation needs 4 bits headroom, headroom can be reduced by 1 \
+ bit due to fPow2Div2() usage */
+#define SF_WET_NRG \
+ (4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \
+ i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \
+ calculation needs 4 bits headroom, headroom can be reduced by 1 \
+ bit due to fPow2Div2() usage */
#define SF_PRODUCT_BP_GF 13
#define SF_PRODUCT_BP_GF_GF 26
#define SF_SCALE 2
@@ -172,18 +184,6 @@ amm-info@iis.fraunhofer.de
STP_SCALE_LIMIT_LO_LD64 = LD64(STP_SCALE_LIMIT_LO*STP_SCALE_LIMIT_LO)
*/
-#define DRY_ENER_WEIGHT(DryEner) DryEner = DryEner >> dry_scale_dmx
-
-#define WET_ENER_WEIGHT(WetEner) WetEner = WetEner << wet_scale_dmx
-
-#define DRY_ENER_SUM_REAL(DryEner, dmxReal, n) \
- DryEner += \
- fMultDiv2(fPow2Div2(dmxReal << SF_DRY), pBP[n]) >> ((2 * SF_DRY) - 2)
-
-#define DRY_ENER_SUM_CPLX(DryEner, dmxReal, dmxImag, n) \
- DryEner += fMultDiv2( \
- fPow2Div2(dmxReal << SF_DRY) + fPow2Div2(dmxImag << SF_DRY), pBP[n])
-
#define CALC_WET_SCALE(dryIdx, wetIdx) \
if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \
scale[wetIdx] = STP_SCALE_LIMIT_HI; \
@@ -206,29 +206,6 @@ struct STP_DEC {
int update_old_ener;
};
-inline void combineSignalReal(FIXP_DBL *hybOutputRealDry,
- FIXP_DBL *hybOutputRealWet, int bands) {
- int n;
-
- for (n = bands - 1; n >= 0; n--) {
- *hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet;
- hybOutputRealDry++, hybOutputRealWet++;
- }
-}
-
-inline void combineSignalRealScale1(FIXP_DBL *hybOutputRealDry,
- FIXP_DBL *hybOutputRealWet, FIXP_DBL scaleX,
- int bands) {
- int n;
-
- for (n = bands - 1; n >= 0; n--) {
- *hybOutputRealDry =
- *hybOutputRealDry +
- (fMultDiv2(*hybOutputRealWet, scaleX) << (SF_SCALE + 1));
- hybOutputRealDry++, hybOutputRealWet++;
- }
-}
-
inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry,
FIXP_DBL *hybOutputImagDry,
FIXP_DBL *hybOutputRealWet,
@@ -236,8 +213,8 @@ inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry,
int n;
for (n = bands - 1; n >= 0; n--) {
- *hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet;
- *hybOutputImagDry = *hybOutputImagDry + *hybOutputImagWet;
+ *hybOutputRealDry = fAddSaturate(*hybOutputRealDry, *hybOutputRealWet);
+ *hybOutputImagDry = fAddSaturate(*hybOutputImagDry, *hybOutputImagWet);
hybOutputRealDry++, hybOutputRealWet++;
hybOutputImagDry++, hybOutputImagWet++;
}
@@ -253,12 +230,14 @@ inline void combineSignalCplxScale1(FIXP_DBL *hybOutputRealDry,
FIXP_DBL scaleY;
for (n = bands - 1; n >= 0; n--) {
scaleY = fMultDiv2(scaleX, *pBP);
- *hybOutputRealDry =
- *hybOutputRealDry +
- (fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 2));
- *hybOutputImagDry =
- *hybOutputImagDry +
- (fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 2));
+ *hybOutputRealDry = SATURATE_LEFT_SHIFT(
+ (*hybOutputRealDry >> 1) +
+ (fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 1)),
+ 1, DFRACT_BITS);
+ *hybOutputImagDry = SATURATE_LEFT_SHIFT(
+ (*hybOutputImagDry >> 1) +
+ (fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 1)),
+ 1, DFRACT_BITS);
hybOutputRealDry++, hybOutputRealWet++;
hybOutputImagDry++, hybOutputImagWet++;
pBP++;
@@ -305,12 +284,10 @@ SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self) {
for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE));
- self->oldWetEnerLD64[ch] =
- FL2FXCONST_DBL(0.34375f); /* 32768.0*32768.0/2^(44-26-10) */
+ self->oldWetEnerLD64[ch] = FL2FXCONST_DBL(0.0);
}
for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) {
- self->oldDryEnerLD64[ch] =
- FL2FXCONST_DBL(0.1875f); /* 32768.0*32768.0/2^(44-26) */
+ self->oldDryEnerLD64[ch] = FL2FXCONST_DBL(0.0);
}
self->BP = BP__FDK;
@@ -364,7 +341,12 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
{
cplxBands = BP_GF_SIZE;
cplxHybBands = self->hybridBands;
- dry_scale_dmx = (2 * SF_DRY) - 2;
+ if (self->treeConfig == TREE_212) {
+ dry_scale_dmx = 2; /* 2 bits to compensate fMultDiv2() and fPow2Div2()
+ used in energy calculation */
+ } else {
+ dry_scale_dmx = (2 * SF_DRY) - 2;
+ }
wet_scale_dmx = 2;
}
@@ -390,8 +372,12 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
CalcLdData(hStpDec->runDryEner[ch] + ABS_THR__FDK);
}
for (ch = 0; ch < self->numOutputChannels; ch++) {
- hStpDec->oldWetEnerLD64[ch] =
- CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK);
+ if (self->treeConfig == TREE_212)
+ hStpDec->oldWetEnerLD64[ch] =
+ CalcLdData(hStpDec->runWetEner[ch] + ABS_THR__FDK);
+ else
+ hStpDec->oldWetEnerLD64[ch] =
+ CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK);
}
} else {
hStpDec->update_old_ener++;
@@ -411,12 +397,33 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
pBP = hStpDec->BP_GF - BP_GF_START;
switch (self->treeConfig) {
case TREE_212:
+ INT sMin, sNorm, sReal, sImag;
+
+ sReal = fMin(getScalefactor(&qmfOutputRealDry[i_LF][BP_GF_START],
+ cplxBands - BP_GF_START),
+ getScalefactor(&qmfOutputRealDry[i_RF][BP_GF_START],
+ cplxBands - BP_GF_START));
+ sImag = fMin(getScalefactor(&qmfOutputImagDry[i_LF][BP_GF_START],
+ cplxBands - BP_GF_START),
+ getScalefactor(&qmfOutputImagDry[i_RF][BP_GF_START],
+ cplxBands - BP_GF_START));
+ sMin = fMin(sReal, sImag) - 1;
+
for (n = BP_GF_START; n < cplxBands; n++) {
- dmxReal0 = qmfOutputRealDry[i_LF][n] + qmfOutputRealDry[i_RF][n];
- dmxImag0 = qmfOutputImagDry[i_LF][n] + qmfOutputImagDry[i_RF][n];
- DRY_ENER_SUM_CPLX(DryEner0, dmxReal0, dmxImag0, n);
+ dmxReal0 = scaleValue(qmfOutputRealDry[i_LF][n], sMin) +
+ scaleValue(qmfOutputRealDry[i_RF][n], sMin);
+ dmxImag0 = scaleValue(qmfOutputImagDry[i_LF][n], sMin) +
+ scaleValue(qmfOutputImagDry[i_RF][n], sMin);
+
+ DryEner0 += (fMultDiv2(fPow2Div2(dmxReal0), pBP[n]) +
+ fMultDiv2(fPow2Div2(dmxImag0), pBP[n])) >>
+ SF_DRY_NRG;
}
- DRY_ENER_WEIGHT(DryEner0);
+
+ sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_DRY_NRG + dry_scale_dmx -
+ (2 * sMin) + nrgScale;
+ DryEner0 = scaleValueSaturate(
+ DryEner0, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
break;
default:;
}
@@ -424,7 +431,7 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
/* normalise the 'direct' signals */
for (ch = 0; ch < self->numInputChannels; ch++) {
- DryEner[ch] = DryEner[ch] << (nrgScale);
+ if (self->treeConfig != TREE_212) DryEner[ch] = DryEner[ch] << nrgScale;
hStpDec->runDryEner[ch] =
fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) +
fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]);
@@ -436,10 +443,8 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
}
}
- if (self->treeConfig == TREE_212) {
- for (; ch < MAX_INPUT_CHANNELS; ch++) {
- DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
- }
+ for (; ch < MAX_INPUT_CHANNELS; ch++) {
+ DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
}
/* normalise the 'diffuse' signals */
@@ -450,14 +455,30 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
}
WetEnerX = FL2FXCONST_DBL(0.0f);
- for (n = BP_GF_START; n < cplxBands; n++) {
- tmp = fPow2Div2(qmfOutputRealWet[ch][n] << SF_WET);
- tmp += fPow2Div2(qmfOutputImagWet[ch][n] << SF_WET);
- WetEnerX += fMultDiv2(tmp, pBP[n]);
- }
- WET_ENER_WEIGHT(WetEnerX);
- WetEnerX = WetEnerX << (nrgScale);
+ if (self->treeConfig == TREE_212) {
+ INT sMin, sNorm;
+
+ sMin = fMin(getScalefactor(&qmfOutputRealWet[ch][BP_GF_START],
+ cplxBands - BP_GF_START),
+ getScalefactor(&qmfOutputImagWet[ch][BP_GF_START],
+ cplxBands - BP_GF_START));
+
+ for (n = BP_GF_START; n < cplxBands; n++) {
+ WetEnerX +=
+ (fMultDiv2(fPow2Div2(scaleValue(qmfOutputRealWet[ch][n], sMin)),
+ pBP[n]) +
+ fMultDiv2(fPow2Div2(scaleValue(qmfOutputImagWet[ch][n], sMin)),
+ pBP[n])) >>
+ SF_WET_NRG;
+ }
+ sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_WET_NRG + wet_scale_dmx -
+ (2 * sMin) + nrgScale;
+ WetEnerX = scaleValueSaturate(
+ WetEnerX, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
+ } else
+ FDK_ASSERT(self->treeConfig == TREE_212);
+
hStpDec->runWetEner[ch] =
fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) +
fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX);
diff --git a/fdk-aac/libSACdec/src/sac_tsd.cpp b/fdk-aac/libSACdec/src/sac_tsd.cpp
index 30acca8..a07447b 100644
--- a/fdk-aac/libSACdec/src/sac_tsd.cpp
+++ b/fdk-aac/libSACdec/src/sac_tsd.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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -123,12 +123,15 @@ static const UCHAR nBitsTsdCW_64slots[64] = {
RAM_ALIGN
LNK_SECTION_CONSTDATA
-static const FIXP_STP phiTsd[8] = {
- STCP(0x7fffffff, 0x00000000), STCP(0x5a82799a, 0x5a82799a),
- STCP(0x00000000, 0x7fffffff), STCP(0xa57d8666, 0x5a82799a),
- STCP(0x80000000, 0x00000000), STCP(0xa57d8666, 0xa57d8666),
- STCP(0x00000000, 0x80000000), STCP(0x5a82799a, 0xa57d8666),
-};
+static const FIXP_DPK phiTsd[8] = {
+ {{(FIXP_DBL)0x7fffffff, (FIXP_DBL)0x00000000}},
+ {{(FIXP_DBL)0x5a82799a, (FIXP_DBL)0x5a82799a}},
+ {{(FIXP_DBL)0x00000000, (FIXP_DBL)0x7fffffff}},
+ {{(FIXP_DBL)0xa57d8666, (FIXP_DBL)0x5a82799a}},
+ {{(FIXP_DBL)0x80000000, (FIXP_DBL)0x00000000}},
+ {{(FIXP_DBL)0xa57d8666, (FIXP_DBL)0xa57d8666}},
+ {{(FIXP_DBL)0x00000000, (FIXP_DBL)0x80000000}},
+ {{(FIXP_DBL)0x5a82799a, (FIXP_DBL)0xa57d8666}}};
/*** Static Functions ***/
static void longmult1(USHORT a[], USHORT b, USHORT d[], int len) {
@@ -333,16 +336,19 @@ void TsdApply(const int numHybridBands, const TSD_DATA *pTsdData, int *pTsdTs,
if (isTrSlot(pTsdData, ts)) {
int k;
- const FIXP_STP *phi = &phiTsd[pTsdData->bsTsdTrPhaseData[ts]];
+ const FIXP_DPK *phi = &phiTsd[pTsdData->bsTsdTrPhaseData[ts]];
FDK_ASSERT((pTsdData->bsTsdTrPhaseData[ts] >= 0) &&
(pTsdData->bsTsdTrPhaseData[ts] < 8));
/* d = d_nonTr + v_direct * exp(j * bsTsdTrPhaseData[ts]/4 * pi ) */
for (k = TSD_START_BAND; k < numHybridBands; k++) {
FIXP_DBL tempReal, tempImag;
- cplxMult(&tempReal, &tempImag, pVdirectReal[k], pVdirectImag[k], *phi);
- pDnonTrReal[k] += tempReal;
- pDnonTrImag[k] += tempImag;
+ cplxMultDiv2(&tempReal, &tempImag, pVdirectReal[k], pVdirectImag[k],
+ *phi);
+ pDnonTrReal[k] = SATURATE_LEFT_SHIFT(
+ (pDnonTrReal[k] >> 2) + (tempReal >> 1), 2, DFRACT_BITS);
+ pDnonTrImag[k] = SATURATE_LEFT_SHIFT(
+ (pDnonTrImag[k] >> 2) + (tempImag >> 1), 2, DFRACT_BITS);
}
}