diff options
author | Fraunhofer IIS FDK <audio-fdk@iis.fraunhofer.de> | 2019-12-19 17:28:15 +0100 |
---|---|---|
committer | Jean-Michel Trivi <jmtrivi@google.com> | 2020-02-14 10:53:51 -0800 |
commit | e016635f0d3a5c7532b00711ce461f97a13f7bc2 (patch) | |
tree | 44d6676c2975eec965bb3e6c2562e1632eaf4385 /libSACdec/src | |
parent | 57c9355de0269afb462ad4a8aa8814f6a6486ff1 (diff) | |
download | fdk-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.cpp | 23 | ||||
-rw-r--r-- | libSACdec/src/sac_dec.h | 5 | ||||
-rw-r--r-- | libSACdec/src/sac_dec_interface.h | 8 | ||||
-rw-r--r-- | libSACdec/src/sac_dec_lib.cpp | 24 | ||||
-rw-r--r-- | libSACdec/src/sac_process.cpp | 30 | ||||
-rw-r--r-- | libSACdec/src/sac_qmf.cpp | 4 | ||||
-rw-r--r-- | libSACdec/src/sac_qmf.h | 4 | ||||
-rw-r--r-- | libSACdec/src/sac_reshapeBBEnv.cpp | 18 | ||||
-rw-r--r-- | libSACdec/src/sac_rom.h | 15 |
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))) |