aboutsummaryrefslogtreecommitdiffstats
path: root/libSACdec/src
diff options
context:
space:
mode:
authorFraunhofer IIS FDK <audio-fdk@iis.fraunhofer.de>2019-12-19 17:28:15 +0100
committerJean-Michel Trivi <jmtrivi@google.com>2020-02-14 10:53:51 -0800
commite016635f0d3a5c7532b00711ce461f97a13f7bc2 (patch)
tree44d6676c2975eec965bb3e6c2562e1632eaf4385 /libSACdec/src
parent57c9355de0269afb462ad4a8aa8814f6a6486ff1 (diff)
downloadfdk-aac-e016635f0d3a5c7532b00711ce461f97a13f7bc2.tar.gz
fdk-aac-e016635f0d3a5c7532b00711ce461f97a13f7bc2.tar.bz2
fdk-aac-e016635f0d3a5c7532b00711ce461f97a13f7bc2.zip
Avoid decoder internal clipping by converting the whole audio sample data path from 16 to 32 bit data width (FDKdec v3.2.0).
Bug: 149514474 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I8a504ab709e42e27a61fe29840212953742283a5
Diffstat (limited to 'libSACdec/src')
-rw-r--r--libSACdec/src/sac_dec.cpp23
-rw-r--r--libSACdec/src/sac_dec.h5
-rw-r--r--libSACdec/src/sac_dec_interface.h8
-rw-r--r--libSACdec/src/sac_dec_lib.cpp24
-rw-r--r--libSACdec/src/sac_process.cpp30
-rw-r--r--libSACdec/src/sac_qmf.cpp4
-rw-r--r--libSACdec/src/sac_qmf.h4
-rw-r--r--libSACdec/src/sac_reshapeBBEnv.cpp18
-rw-r--r--libSACdec/src/sac_rom.h15
9 files changed, 68 insertions, 63 deletions
diff --git a/libSACdec/src/sac_dec.cpp b/libSACdec/src/sac_dec.cpp
index c1832f1..a7b50df 100644
--- a/libSACdec/src/sac_dec.cpp
+++ b/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);
}
}
}
@@ -1416,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/libSACdec/src/sac_dec.h b/libSACdec/src/sac_dec.h
index 992acad..1c3df71 100644
--- a/libSACdec/src/sac_dec.h
+++ b/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/libSACdec/src/sac_dec_interface.h b/libSACdec/src/sac_dec_interface.h
index a2eea92..05a9a75 100644
--- a/libSACdec/src/sac_dec_interface.h
+++ b/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/libSACdec/src/sac_dec_lib.cpp b/libSACdec/src/sac_dec_lib.cpp
index bf6dedf..856a923 100644
--- a/libSACdec/src/sac_dec_lib.cpp
+++ b/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) {
diff --git a/libSACdec/src/sac_process.cpp b/libSACdec/src/sac_process.cpp
index 95128f3..22091a9 100644
--- a/libSACdec/src/sac_process.cpp
+++ b/libSACdec/src/sac_process.cpp
@@ -187,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);
}
}
}
@@ -216,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
@@ -501,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]);
@@ -515,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;
@@ -934,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/libSACdec/src/sac_qmf.cpp b/libSACdec/src/sac_qmf.cpp
index a075490..fd7599d 100644
--- a/libSACdec/src/sac_qmf.cpp
+++ b/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/libSACdec/src/sac_qmf.h b/libSACdec/src/sac_qmf.h
index d1dc837..5cd573e 100644
--- a/libSACdec/src/sac_qmf.h
+++ b/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/libSACdec/src/sac_reshapeBBEnv.cpp b/libSACdec/src/sac_reshapeBBEnv.cpp
index b44ce4e..272d009 100644
--- a/libSACdec/src/sac_reshapeBBEnv.cpp
+++ b/libSACdec/src/sac_reshapeBBEnv.cpp
@@ -253,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,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);
diff --git a/libSACdec/src/sac_rom.h b/libSACdec/src/sac_rom.h
index 38f17f2..d317856 100644
--- a/libSACdec/src/sac_rom.h
+++ b/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)))