diff options
Diffstat (limited to 'libSACdec/src')
-rw-r--r-- | libSACdec/src/sac_bitdec.cpp | 18 | ||||
-rw-r--r-- | libSACdec/src/sac_dec.cpp | 75 | ||||
-rw-r--r-- | libSACdec/src/sac_dec_lib.cpp | 21 | ||||
-rw-r--r-- | libSACdec/src/sac_process.cpp | 20 | ||||
-rw-r--r-- | libSACdec/src/sac_reshapeBBEnv.cpp | 77 | ||||
-rw-r--r-- | libSACdec/src/sac_stp.cpp | 32 |
6 files changed, 159 insertions, 84 deletions
diff --git a/libSACdec/src/sac_bitdec.cpp b/libSACdec/src/sac_bitdec.cpp index 708ddf1..25b3d9e 100644 --- a/libSACdec/src/sac_bitdec.cpp +++ b/libSACdec/src/sac_bitdec.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 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -448,7 +448,6 @@ SACDEC_ERROR SpatialDecParseSpecificConfig( int bsFreqRes, b3DaudioMode = 0; int numHeaderBits; int cfgStartPos, bitsAvailable; - int treeConfig; FDKmemclear(pSpatialSpecificConfig, sizeof(SPATIAL_SPECIFIC_CONFIG)); @@ -489,13 +488,18 @@ SACDEC_ERROR SpatialDecParseSpecificConfig( pSpatialSpecificConfig->freqRes = (SPATIALDEC_FREQ_RES)freqResTable_LD[bsFreqRes]; - treeConfig = FDKreadBits(bitstream, 4); + { + UINT treeConfig = FDKreadBits(bitstream, 4); - if (treeConfig != SPATIALDEC_MODE_RSVD7) { - err = MPS_UNSUPPORTED_CONFIG; - goto bail; + switch (treeConfig) { + case SPATIALDEC_MODE_RSVD7: + pSpatialSpecificConfig->treeConfig = (SPATIALDEC_TREE_CONFIG)treeConfig; + break; + default: + err = MPS_UNSUPPORTED_CONFIG; + goto bail; + } } - pSpatialSpecificConfig->treeConfig = (SPATIALDEC_TREE_CONFIG) treeConfig; { pSpatialSpecificConfig->nOttBoxes = diff --git a/libSACdec/src/sac_dec.cpp b/libSACdec/src/sac_dec.cpp index a7b50df..a26e251 100644 --- a/libSACdec/src/sac_dec.cpp +++ b/libSACdec/src/sac_dec.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 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1098,6 +1098,28 @@ static void SpatialDecApplyBypass(spatialDec *self, FIXP_DBL **hybInputReal, } } +/** + * \brief Set internal error and reset error status + * + * \param self spatialDec handle. + * \param bypassMode pointer to bypassMode. + * \param err error status. + * + * \return error status. + */ +static SACDEC_ERROR SpatialDecSetInternalError(spatialDec *self, + int *bypassMode, + SACDEC_ERROR err) { + *bypassMode = 1; + + if (self->errInt == MPS_OK) { + /* store internal error before it gets overwritten */ + self->errInt = err; + } + + return MPS_OK; +} + /******************************************************************************* Functionname: SpatialDecApplyParameterSets ******************************************************************************* @@ -1118,7 +1140,7 @@ static SACDEC_ERROR SpatialDecApplyParameterSets( const FDK_channelMapDescr *const mapDescr) { SACDEC_ERROR err = MPS_OK; - FIXP_SGL alpha; + FIXP_SGL alpha = FL2FXCONST_SGL(0.0); int ts; int ch; @@ -1141,20 +1163,22 @@ static SACDEC_ERROR SpatialDecApplyParameterSets( ts++, ts_io++) { int currSlot = frame->paramSlot[ps]; + err = (currSlot < ts) ? MPS_WRONG_PARAMETERSETS : MPS_OK; + if (err != MPS_OK) { + err = SpatialDecSetInternalError(self, &bypassMode, err); + } + /* * Get new parameter set */ if (ts == prevSlot + 1) { - err = SpatialDecCalculateM1andM2(self, ps, - frame); /* input: ottCLD, ottICC, ... */ - /* output: M1param(Real/Imag), M2(Real/Imag) */ - if (err != MPS_OK) { - bypassMode = 1; - if (self->errInt == MPS_OK) { - /* store internal error befor it gets overwritten */ - self->errInt = err; + if (bypassMode == 0) { + err = SpatialDecCalculateM1andM2( + self, ps, frame); /* input: ottCLD, ottICC, ... */ + /* output: M1param(Real/Imag), M2(Real/Imag) */ + if (err != MPS_OK) { + err = SpatialDecSetInternalError(self, &bypassMode, err); } - err = MPS_OK; } if ((ps == 0) && (self->bOverwriteM1M2prev != 0)) { @@ -1168,13 +1192,16 @@ static SACDEC_ERROR SpatialDecApplyParameterSets( self->bOverwriteM1M2prev = 0; } - SpatialDecSmoothM1andM2( - self, frame, - ps); /* input: M1param(Real/Imag)(Prev), M2(Real/Imag)(Prev) */ - /* output: M1param(Real/Imag), M2(Real/Imag) */ + if (bypassMode == 0) { + SpatialDecSmoothM1andM2( + self, frame, + ps); /* input: M1param(Real/Imag)(Prev), M2(Real/Imag)(Prev) */ + } /* output: M1param(Real/Imag), M2(Real/Imag) */ } - alpha = FX_DBL2FX_SGL(fDivNorm(ts - prevSlot, currSlot - prevSlot)); + if (bypassMode == 0) { + alpha = FX_DBL2FX_SGL(fDivNorm(ts - prevSlot, currSlot - prevSlot)); + } switch (mode) { case INPUTMODE_QMF_SBR: @@ -1182,15 +1209,17 @@ static SACDEC_ERROR SpatialDecApplyParameterSets( self->bShareDelayWithSBR = 0; /* We got no hybrid delay */ else self->bShareDelayWithSBR = 1; - SpatialDecFeedQMF(self, qmfInDataReal, qmfInDataImag, ts_io, bypassMode, - self->qmfInputReal__FDK, self->qmfInputImag__FDK, - self->numInputChannels); + SpatialDecFeedQMF( + self, qmfInDataReal, qmfInDataImag, ts_io, bypassMode, + self->qmfInputReal__FDK, self->qmfInputImag__FDK, + (bypassMode) ? numInputChannels : self->numInputChannels); break; case INPUTMODE_TIME: self->bShareDelayWithSBR = 0; - SpatialDecQMFAnalysis(self, inData, ts_io, bypassMode, - self->qmfInputReal__FDK, self->qmfInputImag__FDK, - self->numInputChannels); + SpatialDecQMFAnalysis( + self, inData, ts_io, bypassMode, self->qmfInputReal__FDK, + self->qmfInputImag__FDK, + (bypassMode) ? numInputChannels : self->numInputChannels); break; default: break; @@ -1360,7 +1389,7 @@ static SACDEC_ERROR SpatialDecApplyParameterSets( } /* !self->tempShapeConfig == 1 */ } /* !bypassMode */ - if (self->phaseCoding == 1) { + if ((self->phaseCoding == 1) && (bypassMode == 0)) { /* only if bsPhaseCoding == 1 and bsResidualCoding == 0 */ SpatialDecApplyPhase( diff --git a/libSACdec/src/sac_dec_lib.cpp b/libSACdec/src/sac_dec_lib.cpp index 57446f8..d30131f 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 - 2019 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 @@ -700,9 +700,10 @@ bail: SACDEC_ERROR mpegSurroundDecoder_Config( CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs, AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize, - INT stereoConfigIndex, INT coreSbrFrameLengthIndex, INT configBytes, - const UCHAR configMode, UCHAR *configChanged) { + INT numChannels, INT stereoConfigIndex, INT coreSbrFrameLengthIndex, + INT configBytes, const UCHAR configMode, UCHAR *configChanged) { SACDEC_ERROR err = MPS_OK; + INT nInputChannels; SPATIAL_SPECIFIC_CONFIG spatialSpecificConfig; SPATIAL_SPECIFIC_CONFIG *pSsc = &pMpegSurroundDecoder->spatialSpecificConfigBackup; @@ -716,12 +717,18 @@ SACDEC_ERROR mpegSurroundDecoder_Config( err = SpatialDecParseMps212Config( hBs, &spatialSpecificConfig, samplingRate, coreCodec, stereoConfigIndex, coreSbrFrameLengthIndex); + nInputChannels = spatialSpecificConfig.nInputChannels; pSsc = &spatialSpecificConfig; } else { err = SpatialDecParseMps212Config( hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup, samplingRate, coreCodec, stereoConfigIndex, coreSbrFrameLengthIndex); + nInputChannels = + pMpegSurroundDecoder->spatialSpecificConfigBackup.nInputChannels; + } + if ((err == MPS_OK) && (numChannels != nInputChannels)) { + err = MPS_PARSE_ERROR; } break; case AOT_ER_AAC_ELD: @@ -731,11 +738,19 @@ SACDEC_ERROR mpegSurroundDecoder_Config( * into temporarily allocated structure */ err = SpatialDecParseSpecificConfig(hBs, &spatialSpecificConfig, configBytes, coreCodec); + nInputChannels = spatialSpecificConfig.nInputChannels; pSsc = &spatialSpecificConfig; } else { err = SpatialDecParseSpecificConfig( hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup, configBytes, coreCodec); + nInputChannels = + pMpegSurroundDecoder->spatialSpecificConfigBackup.nInputChannels; + } + /* check number of channels for channel_configuration > 0 */ + if ((err == MPS_OK) && (numChannels > 0) && + (numChannels != nInputChannels)) { + err = MPS_PARSE_ERROR; } break; default: 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 bb66277..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 - 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 @@ -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++; } @@ -369,15 +367,15 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) { hStpDec->update_old_ener = 1; for (ch = 0; ch < self->numInputChannels; ch++) { hStpDec->oldDryEnerLD64[ch] = - CalcLdData(hStpDec->runDryEner[ch] + ABS_THR__FDK); + CalcLdData(fAddSaturate(hStpDec->runDryEner[ch], ABS_THR__FDK)); } for (ch = 0; ch < self->numOutputChannels; ch++) { if (self->treeConfig == TREE_212) hStpDec->oldWetEnerLD64[ch] = - CalcLdData(hStpDec->runWetEner[ch] + ABS_THR__FDK); + CalcLdData(fAddSaturate(hStpDec->runWetEner[ch], ABS_THR__FDK)); else hStpDec->oldWetEnerLD64[ch] = - CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK); + CalcLdData(fAddSaturate(hStpDec->runWetEner[ch], ABS_THR2__FDK)); } } else { hStpDec->update_old_ener++; |