diff options
Diffstat (limited to 'fdk-aac/libSACdec/src/sac_process.cpp')
-rw-r--r-- | fdk-aac/libSACdec/src/sac_process.cpp | 175 |
1 files changed, 98 insertions, 77 deletions
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], |