aboutsummaryrefslogtreecommitdiffstats
path: root/libSACdec/src/sac_process.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libSACdec/src/sac_process.cpp')
-rw-r--r--libSACdec/src/sac_process.cpp175
1 files changed, 98 insertions, 77 deletions
diff --git a/libSACdec/src/sac_process.cpp b/libSACdec/src/sac_process.cpp
index 56c72ad..22091a9 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 - 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],