mirror of
https://github.com/mstorsjo/fdk-aac.git
synced 2025-06-05 22:39:13 +02:00
Snap for 6104206 from 47b23c88cf
to rvc-release
Change-Id: I37ae8a78b271948e025a2e6c071453480dcc9a52
This commit is contained in:
22
TEST_MAPPING
Normal file
22
TEST_MAPPING
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"presubmit": [
|
||||
{
|
||||
"name": "CtsMediaTestCases",
|
||||
"options": [
|
||||
{ "include-filter": "android.media.cts.DecoderTest#testCodecResetsM4a" },
|
||||
{ "include-filter": "android.media.cts.DecoderTest#testDecode51M4a" },
|
||||
{ "include-filter": "android.media.cts.DecoderTest#testDecodeAacEldM4a" },
|
||||
{ "include-filter": "android.media.cts.DecoderTest#testDecodeAacLcM4a" },
|
||||
{ "include-filter": "android.media.cts.DecoderTest#testDecodeAacLcMcM4a" },
|
||||
{ "include-filter": "android.media.cts.DecoderTest#testDecodeAacTs" },
|
||||
{ "include-filter": "android.media.cts.DecoderTest#testDecodeHeAacM4a" },
|
||||
{ "include-filter": "android.media.cts.DecoderTest#testDecodeHeAacMcM4a" },
|
||||
{ "include-filter": "android.media.cts.DecoderTest#testDecodeHeAacV2M4a" },
|
||||
{ "include-filter": "android.media.cts.DecoderTest#testDecodeM4a" },
|
||||
{ "include-filter": "android.media.cts.DecoderTest#testDecodeMonoM4a" },
|
||||
{ "include-filter": "android.media.cts.DecoderTestXheAac" },
|
||||
{ "include-filter": "android.media.cts.DecoderTestAacDrc" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@@ -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
|
||||
@@ -1324,6 +1324,10 @@ UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM bs, void *ptr) {
|
||||
/* count ones and store sum in escapePrefixUp */
|
||||
if (carryBit == 1) {
|
||||
escapePrefixUp += 1; /* update conter for ones */
|
||||
if (escapePrefixUp > 8) {
|
||||
pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX;
|
||||
return BODY_SIGN_ESC__ESC_PREFIX;
|
||||
}
|
||||
|
||||
/* store updated counter in sideinfo of current codeword */
|
||||
pEscapeSequenceInfo[codewordOffset] &=
|
||||
|
@@ -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
|
||||
@@ -131,10 +131,12 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
|
||||
FIXP_DBL z0, z2, tmp;
|
||||
|
||||
z2 = x[N / 2 + i];
|
||||
z0 = z2 + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1));
|
||||
z0 = fAddSaturate(z2,
|
||||
(fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1)));
|
||||
|
||||
z[N / 2 + i] = x[N / 2 - 1 - i] +
|
||||
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1));
|
||||
z[N / 2 + i] = fAddSaturate(
|
||||
x[N / 2 - 1 - i],
|
||||
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1)));
|
||||
|
||||
tmp = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) +
|
||||
fMultDiv2(z[i], fb[N + N / 2 + i]));
|
||||
@@ -159,10 +161,12 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
|
||||
FIXP_DBL z0, z2, tmp0, tmp1;
|
||||
|
||||
z2 = x[N / 2 + i];
|
||||
z0 = z2 + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1));
|
||||
z0 = fAddSaturate(z2,
|
||||
(fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1)));
|
||||
|
||||
z[N / 2 + i] = x[N / 2 - 1 - i] +
|
||||
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1));
|
||||
z[N / 2 + i] = fAddSaturate(
|
||||
x[N / 2 - 1 - i],
|
||||
(fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1)));
|
||||
|
||||
tmp0 = (fMultDiv2(z[N / 2 + i], fb[N / 2 - 1 - i]) +
|
||||
fMultDiv2(z[i], fb[N / 2 + i]));
|
||||
|
@@ -465,7 +465,9 @@ void BuildAdaptiveExcitation(
|
||||
/* Note: code[L_SUBFR] and exc2[L_SUBFR] share the same memory!
|
||||
If exc2[i] is written, code[i] will be destroyed!
|
||||
*/
|
||||
#define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC)
|
||||
#define SF_HEADROOM (1)
|
||||
#define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC - SF_HEADROOM)
|
||||
#define SF_GAIN_P2 (SF_GAIN_P - SF_HEADROOM)
|
||||
|
||||
int i;
|
||||
FIXP_DBL tmp, cpe, code_smooth_prev, code_smooth;
|
||||
@@ -477,8 +479,8 @@ void BuildAdaptiveExcitation(
|
||||
cpe = (period_fac >> (2 - SF_PFAC)) + FL2FXCONST_DBL(0.25f);
|
||||
|
||||
/* u'(n) */
|
||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1); /* v(0)*g_p */
|
||||
*exc++ = tmp + (fMultDiv2(code[0], gain_code) << SF);
|
||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1); /* v(0)*g_p */
|
||||
*exc++ = (tmp + (fMultDiv2(code[0], gain_code) << SF)) << SF_HEADROOM;
|
||||
|
||||
/* u(n) */
|
||||
code_smooth_prev = fMultDiv2(*code++, gain_code_smoothed)
|
||||
@@ -487,15 +489,15 @@ void BuildAdaptiveExcitation(
|
||||
code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF; /* c(1) * g_sc */
|
||||
tmp += code_smooth_prev; /* tmp = v(0)*g_p + c(0)*g_sc */
|
||||
cpe_code_smooth = fMultDiv2(cpe, code_smooth);
|
||||
*exc2++ = tmp - cpe_code_smooth;
|
||||
*exc2++ = (tmp - cpe_code_smooth) << SF_HEADROOM;
|
||||
cpe_code_smooth_prev = fMultDiv2(cpe, code_smooth_prev);
|
||||
|
||||
i = L_SUBFR - 2;
|
||||
do /* ARM926: 22 cycles per iteration */
|
||||
{
|
||||
/* u'(n) */
|
||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
|
||||
*exc++ = tmp + (fMultDiv2(code_i, gain_code) << SF);
|
||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1);
|
||||
*exc++ = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM;
|
||||
/* u(n) */
|
||||
tmp += code_smooth; /* += g_sc * c(i) */
|
||||
tmp -= cpe_code_smooth_prev;
|
||||
@@ -503,16 +505,17 @@ void BuildAdaptiveExcitation(
|
||||
code_i = *code++;
|
||||
code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF;
|
||||
cpe_code_smooth = fMultDiv2(cpe, code_smooth);
|
||||
*exc2++ = tmp - cpe_code_smooth; /* tmp - c_pe * g_sc * c(i+1) */
|
||||
*exc2++ = (tmp - cpe_code_smooth)
|
||||
<< SF_HEADROOM; /* tmp - c_pe * g_sc * c(i+1) */
|
||||
} while (--i != 0);
|
||||
|
||||
/* u'(n) */
|
||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
|
||||
*exc = tmp + (fMultDiv2(code_i, gain_code) << SF);
|
||||
tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1);
|
||||
*exc = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM;
|
||||
/* u(n) */
|
||||
tmp += code_smooth;
|
||||
tmp -= cpe_code_smooth_prev;
|
||||
*exc2++ = tmp;
|
||||
*exc2++ = tmp << SF_HEADROOM;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@@ -1018,6 +1018,7 @@ static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,
|
||||
int additionalDrcSetIdPresent, additionalDrcSetIdCount;
|
||||
int dependsOnEqSetPresent, eqChannelGroupCount, tdFilterCascadePresent,
|
||||
subbandGainsPresent, eqTransitionDurationPresent;
|
||||
UCHAR eqChannelGroupForChannel[8];
|
||||
|
||||
FDKpushFor(hBs, 6); /* eqSetId */
|
||||
FDKpushFor(hBs, 4); /* eqSetComplexityLevel */
|
||||
@@ -1067,7 +1068,6 @@ static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,
|
||||
|
||||
eqChannelGroupCount = 0;
|
||||
for (c = 0; c < channelCount; c++) {
|
||||
UCHAR eqChannelGroupForChannel[8];
|
||||
int newGroup = 1;
|
||||
if (c >= 8) return DE_MEMORY_ERROR;
|
||||
eqChannelGroupForChannel[c] = FDKreadBits(hBs, 7);
|
||||
|
@@ -129,15 +129,13 @@ void scaleCplxValues(FIXP_DBL *r_dst, FIXP_DBL *i_dst, const FIXP_DBL *r_src,
|
||||
void scaleValuesWithFactor(FIXP_DBL *vector, FIXP_DBL factor, INT len,
|
||||
INT scalefactor);
|
||||
void scaleValuesSaturate(FIXP_DBL *vector, INT len, INT scalefactor);
|
||||
void scaleValuesSaturate(FIXP_DBL *dst, FIXP_DBL *src, INT len,
|
||||
void scaleValuesSaturate(FIXP_DBL *dst, const FIXP_DBL *src, INT len,
|
||||
INT scalefactor);
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, FIXP_DBL *src, INT len,
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, const FIXP_DBL *src, INT len,
|
||||
INT scalefactor);
|
||||
void scaleValuesSaturate(INT_PCM *dst, FIXP_DBL *src, INT len, INT scalefactor);
|
||||
void scaleValuesSaturate(FIXP_SGL *vector, INT len, INT scalefactor);
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, FIXP_SGL *src, INT len,
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, const FIXP_SGL *src, INT len,
|
||||
INT scalefactor);
|
||||
void scaleValuesSaturate(INT_PCM *dst, INT_PCM *src, INT len, INT scalefactor);
|
||||
INT getScalefactorShort(const SHORT *vector, INT len);
|
||||
INT getScalefactorPCM(const INT_PCM *vector, INT len, INT stride);
|
||||
INT getScalefactor(const FIXP_DBL *vector, INT len);
|
||||
|
@@ -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
|
||||
@@ -227,7 +227,7 @@ static inline int SpatialDecGetQmfBand(int paramBand, const UCHAR *tab) {
|
||||
}
|
||||
|
||||
#define DUCKER_MAX_NRG_SCALE (24)
|
||||
#define DUCKER_HEADROOM_BITS (3)
|
||||
#define DUCKER_HEADROOM_BITS (2)
|
||||
|
||||
#define FILTER_SF (2)
|
||||
|
||||
@@ -606,10 +606,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
|
||||
dataImagIn += start;
|
||||
dataRealOut += start;
|
||||
dataImagOut += start;
|
||||
#ifdef FUNCTION_DecorrFilterApplyPASS_func1
|
||||
DecorrFilterApplyPASS_func1(i, dataRealIn, dataImagIn, dataRealOut,
|
||||
dataImagOut, pDelayBuffer, offset);
|
||||
#else
|
||||
do {
|
||||
FIXP_DBL delay_re, delay_im, real, imag;
|
||||
|
||||
@@ -623,7 +619,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
|
||||
*dataImagOut++ = delay_im;
|
||||
pDelayBuffer += offset;
|
||||
} while (--i != 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1061,24 +1056,15 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
|
||||
FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
|
||||
|
||||
if (maxVal == FL2FXCONST_DBL(-1.0f)) {
|
||||
#ifdef FUNCTION_DuckerCalcEnergy_func2
|
||||
maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
|
||||
maxHybBand, maxHybridBand);
|
||||
#else
|
||||
FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
|
||||
for (qs = startHybBand; qs <= maxHybBand; qs++) {
|
||||
localMaxVal |= fAbs(inputReal[qs]);
|
||||
localMaxVal |= fAbs(inputImag[qs]);
|
||||
}
|
||||
for (; qs <= maxHybridBand; qs++) {
|
||||
localMaxVal |= fAbs(inputReal[qs]);
|
||||
}
|
||||
maxVal = localMaxVal;
|
||||
#endif
|
||||
clz = fMin(getScalefactor(&inputReal[startHybBand],
|
||||
fMax(0, maxHybridBand - startHybBand + 1)),
|
||||
getScalefactor(&inputImag[startHybBand],
|
||||
fMax(0, maxHybBand - startHybBand + 1)));
|
||||
} else {
|
||||
clz = CntLeadingZeros(maxVal) - 1;
|
||||
}
|
||||
|
||||
clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
|
||||
clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
|
||||
clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
|
||||
*nrgScale = (SCHAR)clz << 1;
|
||||
|
||||
/* Initialize pb since it would stay uninitialized for the case startHybBand
|
||||
@@ -1086,9 +1072,10 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
|
||||
pb = SpatialDecGetProcessingBand(maxHybBand, self->mapHybBands2ProcBands);
|
||||
for (qs = startHybBand; qs <= maxHybBand; qs++) {
|
||||
pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
|
||||
energy[pb] =
|
||||
fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
|
||||
fPow2Div2(inputImag[qs] << clz));
|
||||
energy[pb] = SATURATE_LEFT_SHIFT(
|
||||
(energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
|
||||
(fPow2Div2(inputImag[qs] << clz) >> 1),
|
||||
1, DFRACT_BITS);
|
||||
}
|
||||
pb++;
|
||||
|
||||
@@ -1112,43 +1099,29 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
|
||||
maxVal = inputMaxVal;
|
||||
|
||||
if (maxVal == FL2FXCONST_DBL(-1.0f)) {
|
||||
#ifdef FUNCTION_DuckerCalcEnergy_func2
|
||||
maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand,
|
||||
maxHybBand, maxHybridBand);
|
||||
#else
|
||||
FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f);
|
||||
for (qs = startHybBand; qs <= maxHybBand; qs++) {
|
||||
localMaxVal |= fAbs(inputReal[qs]);
|
||||
localMaxVal |= fAbs(inputImag[qs]);
|
||||
}
|
||||
for (; qs <= maxHybridBand; qs++) {
|
||||
localMaxVal |= fAbs(inputReal[qs]);
|
||||
}
|
||||
maxVal = localMaxVal;
|
||||
#endif
|
||||
clz = fMin(getScalefactor(&inputReal[startHybBand],
|
||||
fMax(0, maxHybridBand - startHybBand + 1)),
|
||||
getScalefactor(&inputImag[startHybBand],
|
||||
fMax(0, maxHybBand - startHybBand + 1)));
|
||||
} else {
|
||||
clz = CntLeadingZeros(maxVal) - 1;
|
||||
}
|
||||
|
||||
clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS);
|
||||
clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
|
||||
clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
|
||||
*nrgScale = (SCHAR)clz << 1;
|
||||
|
||||
#ifdef FUNCTION_DuckerCalcEnergy_func4
|
||||
DuckerCalcEnergy_func4(inputReal, inputImag, energy,
|
||||
self->mapHybBands2ProcBands, clz, startHybBand,
|
||||
maxHybBand, maxHybridBand);
|
||||
#else
|
||||
for (qs = startHybBand; qs <= maxHybBand; qs++) {
|
||||
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
|
||||
energy[pb] =
|
||||
fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) +
|
||||
fPow2Div2(inputImag[qs] << clz));
|
||||
energy[pb] = SATURATE_LEFT_SHIFT(
|
||||
(energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
|
||||
(fPow2Div2(inputImag[qs] << clz) >> 1),
|
||||
1, DFRACT_BITS);
|
||||
}
|
||||
|
||||
for (; qs <= maxHybridBand; qs++) {
|
||||
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
|
||||
energy[pb] = fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz));
|
||||
}
|
||||
#endif /* FUNCTION_DuckerCalcEnergy_func4 */
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1295,10 +1268,6 @@ static INT DuckerApply(DUCKER_INSTANCE *const self,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FUNCTION_DuckerApply_func1
|
||||
qs = DuckerApply_func1(qs, hybBands, qs_next, outputReal, outputImag,
|
||||
duckGain);
|
||||
#else
|
||||
/* general gain*output section */
|
||||
if (qs < hybBands) { /* true for about 39% */
|
||||
for (; qs < qs_next; qs++) { /* runs about 2 times */
|
||||
@@ -1310,7 +1279,6 @@ static INT DuckerApply(DUCKER_INSTANCE *const self,
|
||||
outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} /* pb */
|
||||
|
||||
self->headroomSmoothDirRevNrg =
|
||||
|
@@ -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
|
||||
@@ -489,18 +489,18 @@ void dst_IV(FIXP_DBL *pDat, int L, int *pDat_e) {
|
||||
for (i = 0; i < M - 1; i += 2, pDat_0 += 2, pDat_1 -= 2) {
|
||||
FIXP_DBL accu1, accu2, accu3, accu4;
|
||||
|
||||
accu1 = pDat_1[1];
|
||||
accu2 = -pDat_0[0];
|
||||
accu3 = pDat_0[1];
|
||||
accu4 = -pDat_1[0];
|
||||
accu1 = pDat_1[1] >> 1;
|
||||
accu2 = -(pDat_0[0] >> 1);
|
||||
accu3 = pDat_0[1] >> 1;
|
||||
accu4 = -(pDat_1[0] >> 1);
|
||||
|
||||
cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
|
||||
cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]);
|
||||
|
||||
pDat_0[0] = accu2 >> 1;
|
||||
pDat_0[1] = accu1 >> 1;
|
||||
pDat_1[0] = accu4 >> 1;
|
||||
pDat_1[1] = -(accu3 >> 1);
|
||||
pDat_0[0] = accu2;
|
||||
pDat_0[1] = accu1;
|
||||
pDat_1[0] = accu4;
|
||||
pDat_1[1] = -accu3;
|
||||
}
|
||||
if (M & 1) {
|
||||
FIXP_DBL accu1, accu2;
|
||||
|
@@ -609,9 +609,9 @@ inline static void qmfInverseModulationLP_even(
|
||||
FIXP_DBL *RESTRICT tImag = pTimeOut + L;
|
||||
|
||||
/* Move input to output vector with offset */
|
||||
scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand);
|
||||
scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
|
||||
synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
|
||||
scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb, scaleFactorLowBand);
|
||||
scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
|
||||
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
||||
FDKmemclear(&tReal[0 + synQmf->usb], (L - synQmf->usb) * sizeof(FIXP_DBL));
|
||||
|
||||
/* Dct type-2 transform */
|
||||
@@ -662,9 +662,9 @@ inline static void qmfInverseModulationLP_odd(
|
||||
int shift = 0;
|
||||
|
||||
/* Move input to output vector with offset */
|
||||
scaleValues(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand);
|
||||
scaleValues(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb,
|
||||
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
||||
scaleValuesSaturate(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand);
|
||||
scaleValuesSaturate(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb,
|
||||
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
||||
FDKmemclear(pTimeOut + M + synQmf->usb, (L - synQmf->usb) * sizeof(FIXP_DBL));
|
||||
|
||||
dct_IV(pTimeOut + M, L, &shift);
|
||||
@@ -698,26 +698,27 @@ inline static void qmfInverseModulationHQ(
|
||||
FIXP_DBL *RESTRICT tImag = pWorkBuffer + L;
|
||||
|
||||
if (synQmf->flags & QMF_FLAG_CLDFB) {
|
||||
for (i = 0; i < synQmf->lsb; i++) {
|
||||
cplxMult(&tImag[i], &tReal[i], scaleValue(qmfImag[i], scaleFactorLowBand),
|
||||
scaleValue(qmfReal[i], scaleFactorLowBand), synQmf->t_cos[i],
|
||||
synQmf->t_sin[i]);
|
||||
}
|
||||
for (; i < synQmf->usb; i++) {
|
||||
cplxMult(&tImag[i], &tReal[i],
|
||||
scaleValue(qmfImag[i], scaleFactorHighBand),
|
||||
scaleValue(qmfReal[i], scaleFactorHighBand), synQmf->t_cos[i],
|
||||
synQmf->t_sin[i]);
|
||||
for (i = 0; i < synQmf->usb; i++) {
|
||||
cplxMultDiv2(&tImag[i], &tReal[i], qmfImag[i], qmfReal[i],
|
||||
synQmf->t_cos[i], synQmf->t_sin[i]);
|
||||
}
|
||||
scaleValuesSaturate(&tReal[0], synQmf->lsb, scaleFactorLowBand + 1);
|
||||
scaleValuesSaturate(&tReal[0 + synQmf->lsb], synQmf->usb - synQmf->lsb,
|
||||
scaleFactorHighBand + 1);
|
||||
scaleValuesSaturate(&tImag[0], synQmf->lsb, scaleFactorLowBand + 1);
|
||||
scaleValuesSaturate(&tImag[0 + synQmf->lsb], synQmf->usb - synQmf->lsb,
|
||||
scaleFactorHighBand + 1);
|
||||
}
|
||||
|
||||
if ((synQmf->flags & QMF_FLAG_CLDFB) == 0) {
|
||||
scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand);
|
||||
scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
|
||||
synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
|
||||
scaleValues(&tImag[0], &qmfImag[0], synQmf->lsb, (int)scaleFactorLowBand);
|
||||
scaleValues(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb],
|
||||
synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand);
|
||||
scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb,
|
||||
scaleFactorLowBand);
|
||||
scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
|
||||
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
||||
scaleValuesSaturate(&tImag[0], &qmfImag[0], synQmf->lsb,
|
||||
scaleFactorLowBand);
|
||||
scaleValuesSaturate(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb],
|
||||
synQmf->usb - synQmf->lsb, scaleFactorHighBand);
|
||||
}
|
||||
|
||||
FDKmemclear(&tReal[synQmf->usb],
|
||||
|
@@ -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
|
||||
@@ -250,10 +250,10 @@ void scaleValuesSaturate(FIXP_DBL *vector, /*!< Vector */
|
||||
*/
|
||||
#define FUNCTION_scaleValuesSaturate_DBL_DBL
|
||||
SCALE_INLINE
|
||||
void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
|
||||
FIXP_DBL *src, /*!< Input */
|
||||
INT len, /*!< Length */
|
||||
INT scalefactor /*!< Scalefactor */
|
||||
void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
|
||||
const FIXP_DBL *src, /*!< Input */
|
||||
INT len, /*!< Length */
|
||||
INT scalefactor /*!< Scalefactor */
|
||||
) {
|
||||
INT i;
|
||||
|
||||
@@ -285,10 +285,10 @@ void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */
|
||||
*/
|
||||
#define FUNCTION_scaleValuesSaturate_SGL_DBL
|
||||
SCALE_INLINE
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
|
||||
FIXP_DBL *src, /*!< Input */
|
||||
INT len, /*!< Length */
|
||||
INT scalefactor) /*!< Scalefactor */
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
|
||||
const FIXP_DBL *src, /*!< Input */
|
||||
INT len, /*!< Length */
|
||||
INT scalefactor) /*!< Scalefactor */
|
||||
{
|
||||
INT i;
|
||||
scalefactor = fixmax_I(fixmin_I(scalefactor, (INT)DFRACT_BITS - 1),
|
||||
@@ -345,10 +345,10 @@ void scaleValuesSaturate(FIXP_SGL *vector, /*!< Vector */
|
||||
*/
|
||||
#define FUNCTION_scaleValuesSaturate_SGL_SGL
|
||||
SCALE_INLINE
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
|
||||
FIXP_SGL *src, /*!< Input */
|
||||
INT len, /*!< Length */
|
||||
INT scalefactor /*!< Scalefactor */
|
||||
void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */
|
||||
const FIXP_SGL *src, /*!< Input */
|
||||
INT len, /*!< Length */
|
||||
INT scalefactor /*!< Scalefactor */
|
||||
) {
|
||||
INT i;
|
||||
|
||||
|
@@ -1325,9 +1325,9 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
|
||||
CSTpCallBacks *cb) {
|
||||
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
|
||||
CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig;
|
||||
ASC_ELD_EXT_TYPE eldExtType;
|
||||
UINT eldExtType;
|
||||
int eldExtLen, len, cnt, ldSbrLen = 0, eldExtLenSum, numSbrHeader = 0,
|
||||
sbrIndex;
|
||||
sbrIndex, eldExtCnt = 0;
|
||||
|
||||
unsigned char downscale_fill_nibble;
|
||||
|
||||
@@ -1394,9 +1394,8 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
|
||||
eldExtLenSum = FDKgetValidBits(hBs);
|
||||
esc->m_downscaledSamplingFrequency = asc->m_samplingFrequency;
|
||||
/* parse ExtTypeConfigData */
|
||||
while (
|
||||
((eldExtType = (ASC_ELD_EXT_TYPE)FDKreadBits(hBs, 4)) != ELDEXT_TERM) &&
|
||||
((INT)FDKgetValidBits(hBs) >= 0)) {
|
||||
while (((eldExtType = FDKreadBits(hBs, 4)) != ELDEXT_TERM) &&
|
||||
((INT)FDKgetValidBits(hBs) >= 0) && (eldExtCnt++ < 15)) {
|
||||
eldExtLen = len = FDKreadBits(hBs, 4);
|
||||
if (len == 0xf) {
|
||||
len = FDKreadBits(hBs, 8);
|
||||
@@ -1455,6 +1454,9 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (eldExtType != ELDEXT_TERM) {
|
||||
return TRANSPORTDEC_PARSE_ERROR;
|
||||
}
|
||||
|
||||
if ((INT)FDKgetValidBits(hBs) < 0) {
|
||||
return TRANSPORTDEC_PARSE_ERROR;
|
||||
|
@@ -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
|
||||
@@ -239,8 +239,8 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn,
|
||||
tmp1 = (FIXP_DBL)0;
|
||||
for (j = 0; j < channels; j++) {
|
||||
tmp2 = PCM_LIM2FIXP_DBL(samplesIn[j]);
|
||||
tmp2 = fAbs(tmp2);
|
||||
tmp2 = FIXP_DBL(INT(tmp2) ^ INT((tmp2 >> (SAMPLE_BITS_LIM - 1))));
|
||||
tmp2 =
|
||||
(tmp2 == (FIXP_DBL)MINVAL_DBL) ? (FIXP_DBL)MAXVAL_DBL : fAbs(tmp2);
|
||||
tmp1 = fMax(tmp1, tmp2);
|
||||
}
|
||||
tmp = fMult(tmp1, additionalGain);
|
||||
|
@@ -1610,6 +1610,10 @@ static SACDEC_ERROR mapIndexData(
|
||||
} /* for( i = 0 ; i < numParameterSets; i++ ) */
|
||||
|
||||
if (extendFrame) {
|
||||
if (paramType == t_IPD) {
|
||||
llData->bsQuantCoarseXXX[numParameterSets] =
|
||||
llData->bsQuantCoarseXXX[numParameterSets - 1];
|
||||
}
|
||||
for (band = startBand; band < stopBand; band++) {
|
||||
outputDataIdx[xttIdx][numParameterSets][band] =
|
||||
outputDataIdx[xttIdx][numParameterSets - 1][band];
|
||||
|
@@ -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
|
||||
@@ -106,6 +106,8 @@ amm-info@iis.fraunhofer.de
|
||||
#include "FDK_matrixCalloc.h"
|
||||
#include "sac_rom.h"
|
||||
|
||||
#define SF_FREQ_DOMAIN_HEADROOM (2 * (1))
|
||||
|
||||
#define BP_GF_START 6
|
||||
#define BP_GF_SIZE 25
|
||||
#define HP_SIZE 9
|
||||
@@ -114,6 +116,16 @@ amm-info@iis.fraunhofer.de
|
||||
#define SF_WET 5
|
||||
#define SF_DRY \
|
||||
3 /* SF_DRY == 2 would produce good conformance test results as well */
|
||||
#define SF_DRY_NRG \
|
||||
(4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \
|
||||
i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \
|
||||
calculation needs 4 bits headroom, headroom can be reduced by 1 \
|
||||
bit due to fPow2Div2() usage */
|
||||
#define SF_WET_NRG \
|
||||
(4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \
|
||||
i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \
|
||||
calculation needs 4 bits headroom, headroom can be reduced by 1 \
|
||||
bit due to fPow2Div2() usage */
|
||||
#define SF_PRODUCT_BP_GF 13
|
||||
#define SF_PRODUCT_BP_GF_GF 26
|
||||
#define SF_SCALE 2
|
||||
@@ -172,18 +184,6 @@ amm-info@iis.fraunhofer.de
|
||||
STP_SCALE_LIMIT_LO_LD64 = LD64(STP_SCALE_LIMIT_LO*STP_SCALE_LIMIT_LO)
|
||||
*/
|
||||
|
||||
#define DRY_ENER_WEIGHT(DryEner) DryEner = DryEner >> dry_scale_dmx
|
||||
|
||||
#define WET_ENER_WEIGHT(WetEner) WetEner = WetEner << wet_scale_dmx
|
||||
|
||||
#define DRY_ENER_SUM_REAL(DryEner, dmxReal, n) \
|
||||
DryEner += \
|
||||
fMultDiv2(fPow2Div2(dmxReal << SF_DRY), pBP[n]) >> ((2 * SF_DRY) - 2)
|
||||
|
||||
#define DRY_ENER_SUM_CPLX(DryEner, dmxReal, dmxImag, n) \
|
||||
DryEner += fMultDiv2( \
|
||||
fPow2Div2(dmxReal << SF_DRY) + fPow2Div2(dmxImag << SF_DRY), pBP[n])
|
||||
|
||||
#define CALC_WET_SCALE(dryIdx, wetIdx) \
|
||||
if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \
|
||||
scale[wetIdx] = STP_SCALE_LIMIT_HI; \
|
||||
@@ -305,12 +305,10 @@ SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self) {
|
||||
|
||||
for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
|
||||
self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE));
|
||||
self->oldWetEnerLD64[ch] =
|
||||
FL2FXCONST_DBL(0.34375f); /* 32768.0*32768.0/2^(44-26-10) */
|
||||
self->oldWetEnerLD64[ch] = FL2FXCONST_DBL(0.0);
|
||||
}
|
||||
for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) {
|
||||
self->oldDryEnerLD64[ch] =
|
||||
FL2FXCONST_DBL(0.1875f); /* 32768.0*32768.0/2^(44-26) */
|
||||
self->oldDryEnerLD64[ch] = FL2FXCONST_DBL(0.0);
|
||||
}
|
||||
|
||||
self->BP = BP__FDK;
|
||||
@@ -364,7 +362,12 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
||||
{
|
||||
cplxBands = BP_GF_SIZE;
|
||||
cplxHybBands = self->hybridBands;
|
||||
dry_scale_dmx = (2 * SF_DRY) - 2;
|
||||
if (self->treeConfig == TREE_212) {
|
||||
dry_scale_dmx = 2; /* 2 bits to compensate fMultDiv2() and fPow2Div2()
|
||||
used in energy calculation */
|
||||
} else {
|
||||
dry_scale_dmx = (2 * SF_DRY) - 2;
|
||||
}
|
||||
wet_scale_dmx = 2;
|
||||
}
|
||||
|
||||
@@ -390,8 +393,12 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
||||
CalcLdData(hStpDec->runDryEner[ch] + ABS_THR__FDK);
|
||||
}
|
||||
for (ch = 0; ch < self->numOutputChannels; ch++) {
|
||||
hStpDec->oldWetEnerLD64[ch] =
|
||||
CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK);
|
||||
if (self->treeConfig == TREE_212)
|
||||
hStpDec->oldWetEnerLD64[ch] =
|
||||
CalcLdData(hStpDec->runWetEner[ch] + ABS_THR__FDK);
|
||||
else
|
||||
hStpDec->oldWetEnerLD64[ch] =
|
||||
CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK);
|
||||
}
|
||||
} else {
|
||||
hStpDec->update_old_ener++;
|
||||
@@ -411,12 +418,33 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
||||
pBP = hStpDec->BP_GF - BP_GF_START;
|
||||
switch (self->treeConfig) {
|
||||
case TREE_212:
|
||||
INT sMin, sNorm, sReal, sImag;
|
||||
|
||||
sReal = fMin(getScalefactor(&qmfOutputRealDry[i_LF][BP_GF_START],
|
||||
cplxBands - BP_GF_START),
|
||||
getScalefactor(&qmfOutputRealDry[i_RF][BP_GF_START],
|
||||
cplxBands - BP_GF_START));
|
||||
sImag = fMin(getScalefactor(&qmfOutputImagDry[i_LF][BP_GF_START],
|
||||
cplxBands - BP_GF_START),
|
||||
getScalefactor(&qmfOutputImagDry[i_RF][BP_GF_START],
|
||||
cplxBands - BP_GF_START));
|
||||
sMin = fMin(sReal, sImag) - 1;
|
||||
|
||||
for (n = BP_GF_START; n < cplxBands; n++) {
|
||||
dmxReal0 = qmfOutputRealDry[i_LF][n] + qmfOutputRealDry[i_RF][n];
|
||||
dmxImag0 = qmfOutputImagDry[i_LF][n] + qmfOutputImagDry[i_RF][n];
|
||||
DRY_ENER_SUM_CPLX(DryEner0, dmxReal0, dmxImag0, n);
|
||||
dmxReal0 = scaleValue(qmfOutputRealDry[i_LF][n], sMin) +
|
||||
scaleValue(qmfOutputRealDry[i_RF][n], sMin);
|
||||
dmxImag0 = scaleValue(qmfOutputImagDry[i_LF][n], sMin) +
|
||||
scaleValue(qmfOutputImagDry[i_RF][n], sMin);
|
||||
|
||||
DryEner0 += (fMultDiv2(fPow2Div2(dmxReal0), pBP[n]) +
|
||||
fMultDiv2(fPow2Div2(dmxImag0), pBP[n])) >>
|
||||
SF_DRY_NRG;
|
||||
}
|
||||
DRY_ENER_WEIGHT(DryEner0);
|
||||
|
||||
sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_DRY_NRG + dry_scale_dmx -
|
||||
(2 * sMin) + nrgScale;
|
||||
DryEner0 = scaleValueSaturate(
|
||||
DryEner0, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
@@ -424,7 +452,7 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
||||
|
||||
/* normalise the 'direct' signals */
|
||||
for (ch = 0; ch < self->numInputChannels; ch++) {
|
||||
DryEner[ch] = DryEner[ch] << (nrgScale);
|
||||
if (self->treeConfig != TREE_212) DryEner[ch] = DryEner[ch] << nrgScale;
|
||||
hStpDec->runDryEner[ch] =
|
||||
fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) +
|
||||
fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]);
|
||||
@@ -436,10 +464,8 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
||||
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
|
||||
}
|
||||
}
|
||||
if (self->treeConfig == TREE_212) {
|
||||
for (; ch < MAX_INPUT_CHANNELS; ch++) {
|
||||
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
|
||||
}
|
||||
for (; ch < MAX_INPUT_CHANNELS; ch++) {
|
||||
DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
|
||||
}
|
||||
|
||||
/* normalise the 'diffuse' signals */
|
||||
@@ -450,14 +476,30 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
|
||||
}
|
||||
|
||||
WetEnerX = FL2FXCONST_DBL(0.0f);
|
||||
for (n = BP_GF_START; n < cplxBands; n++) {
|
||||
tmp = fPow2Div2(qmfOutputRealWet[ch][n] << SF_WET);
|
||||
tmp += fPow2Div2(qmfOutputImagWet[ch][n] << SF_WET);
|
||||
WetEnerX += fMultDiv2(tmp, pBP[n]);
|
||||
}
|
||||
WET_ENER_WEIGHT(WetEnerX);
|
||||
|
||||
WetEnerX = WetEnerX << (nrgScale);
|
||||
if (self->treeConfig == TREE_212) {
|
||||
INT sMin, sNorm;
|
||||
|
||||
sMin = fMin(getScalefactor(&qmfOutputRealWet[ch][BP_GF_START],
|
||||
cplxBands - BP_GF_START),
|
||||
getScalefactor(&qmfOutputImagWet[ch][BP_GF_START],
|
||||
cplxBands - BP_GF_START));
|
||||
|
||||
for (n = BP_GF_START; n < cplxBands; n++) {
|
||||
WetEnerX +=
|
||||
(fMultDiv2(fPow2Div2(scaleValue(qmfOutputRealWet[ch][n], sMin)),
|
||||
pBP[n]) +
|
||||
fMultDiv2(fPow2Div2(scaleValue(qmfOutputImagWet[ch][n], sMin)),
|
||||
pBP[n])) >>
|
||||
SF_WET_NRG;
|
||||
}
|
||||
sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_WET_NRG + wet_scale_dmx -
|
||||
(2 * sMin) + nrgScale;
|
||||
WetEnerX = scaleValueSaturate(
|
||||
WetEnerX, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
|
||||
} else
|
||||
FDK_ASSERT(self->treeConfig == TREE_212);
|
||||
|
||||
hStpDec->runWetEner[ch] =
|
||||
fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) +
|
||||
fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX);
|
||||
|
@@ -151,6 +151,9 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
#include "genericStds.h" /* need FDKpow() for debug outputs */
|
||||
|
||||
#define MAX_SFB_NRG_HEADROOM (1)
|
||||
#define MAX_VAL_NRG_HEADROOM ((((FIXP_DBL)MAXVAL_DBL) >> MAX_SFB_NRG_HEADROOM))
|
||||
|
||||
typedef struct {
|
||||
FIXP_DBL nrgRef[MAX_FREQ_COEFFS];
|
||||
FIXP_DBL nrgEst[MAX_FREQ_COEFFS];
|
||||
@@ -986,7 +989,8 @@ void calculateSbrEnvelope(
|
||||
*/
|
||||
if (!useLP)
|
||||
adj_e = h_sbr_cal_env->filtBufferNoise_e -
|
||||
getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands);
|
||||
getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands) +
|
||||
(INT)MAX_SFB_NRG_HEADROOM;
|
||||
|
||||
/*
|
||||
Scan for maximum reference energy to be able
|
||||
@@ -1006,7 +1010,7 @@ void calculateSbrEnvelope(
|
||||
- Smoothing can smear high gains of the previous envelope into the
|
||||
current
|
||||
*/
|
||||
maxSfbNrg_e += 6;
|
||||
maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
|
||||
|
||||
adj_e = maxSfbNrg_e;
|
||||
// final_e should not exist for PVC fixfix framing
|
||||
@@ -1032,7 +1036,7 @@ void calculateSbrEnvelope(
|
||||
- Smoothing can smear high gains of the previous envelope into the
|
||||
current
|
||||
*/
|
||||
maxSfbNrg_e += 6;
|
||||
maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
|
||||
|
||||
if (borders[i] < hHeaderData->numberTimeSlots)
|
||||
/* This envelope affects timeslots that belong to the output frame */
|
||||
@@ -2426,6 +2430,9 @@ static void adjustTimeSlot_EldGrid(
|
||||
const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0];
|
||||
const INT *p_harmonicPhase = &harmonicPhase[harmIndex][0];
|
||||
|
||||
const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
|
||||
const FIXP_DBL min_val = -max_val;
|
||||
|
||||
*(ptrReal - 1) = fAddSaturate(
|
||||
*(ptrReal - 1),
|
||||
SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]),
|
||||
@@ -2438,7 +2445,8 @@ static void adjustTimeSlot_EldGrid(
|
||||
FIXP_DBL sineLevel_curr = *pSineLevel++;
|
||||
phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
|
||||
|
||||
signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
|
||||
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
|
||||
<< scale_change;
|
||||
sbNoise = *pNoiseLevel++;
|
||||
if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
|
||||
signalReal +=
|
||||
@@ -2472,7 +2480,8 @@ static void adjustTimeSlot_EldGrid(
|
||||
FIXP_DBL sineLevel_curr = *pSineLevel++;
|
||||
phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
|
||||
|
||||
signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
|
||||
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
|
||||
<< scale_change;
|
||||
sbNoise = *pNoiseLevel++;
|
||||
if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
|
||||
signalReal +=
|
||||
@@ -2512,6 +2521,8 @@ static void adjustTimeSlotLC(
|
||||
FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev;
|
||||
int tone_count = 0;
|
||||
int sineSign = 1;
|
||||
const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
|
||||
const FIXP_DBL min_val = -max_val;
|
||||
|
||||
#define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f))
|
||||
#define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.16773f))
|
||||
@@ -2527,7 +2538,8 @@ static void adjustTimeSlotLC(
|
||||
of the signal and should be carried out with full accuracy
|
||||
(supplying #FRACT_BITS valid bits).
|
||||
*/
|
||||
signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
|
||||
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
|
||||
<< scale_change;
|
||||
sineLevel = *pSineLevel++;
|
||||
sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
|
||||
|
||||
@@ -2555,10 +2567,10 @@ static void adjustTimeSlotLC(
|
||||
|
||||
/* save switch and compare operations and reduce to XOR statement */
|
||||
if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) {
|
||||
*(ptrReal - 1) += tmp1;
|
||||
*(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), tmp1);
|
||||
signalReal -= tmp2;
|
||||
} else {
|
||||
*(ptrReal - 1) -= tmp1;
|
||||
*(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), -tmp1);
|
||||
signalReal += tmp2;
|
||||
}
|
||||
*ptrReal++ = signalReal;
|
||||
@@ -2589,7 +2601,9 @@ static void adjustTimeSlotLC(
|
||||
|
||||
/* The next multiplication constitutes the actual envelope adjustment of
|
||||
* the signal. */
|
||||
signalReal += fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
|
||||
signalReal +=
|
||||
fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
|
||||
<< scale_change;
|
||||
|
||||
pNoiseLevel++;
|
||||
*ptrReal++ = signalReal;
|
||||
@@ -2602,7 +2616,8 @@ static void adjustTimeSlotLC(
|
||||
index++;
|
||||
/* The next multiplication constitutes the actual envelope adjustment of
|
||||
* the signal. */
|
||||
signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change);
|
||||
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
|
||||
<< scale_change;
|
||||
|
||||
if (*pSineLevel++ != FL2FXCONST_DBL(0.0f))
|
||||
tone_count++;
|
||||
@@ -2630,7 +2645,8 @@ static void adjustTimeSlotLC(
|
||||
index++;
|
||||
/* The next multiplication constitutes the actual envelope adjustment of the
|
||||
* signal. */
|
||||
signalReal = fMultDiv2(*ptrReal, *pGain) << ((int)scale_change);
|
||||
signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f));
|
||||
sineLevel = pSineLevel[0];
|
||||
|
||||
@@ -2699,6 +2715,9 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
||||
/*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
|
||||
int index = *ptrPhaseIndex;
|
||||
int shift;
|
||||
FIXP_DBL max_val_noise = 0, min_val_noise = 0;
|
||||
const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
|
||||
const FIXP_DBL min_val = -max_val;
|
||||
|
||||
*ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
|
||||
|
||||
@@ -2708,6 +2727,8 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
||||
shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
|
||||
} else {
|
||||
shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
|
||||
max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
|
||||
min_val_noise = -max_val_noise;
|
||||
}
|
||||
|
||||
if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
|
||||
@@ -2723,8 +2744,10 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
||||
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
|
||||
fMult(direct_ratio, noiseLevel[k]);
|
||||
} else {
|
||||
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) +
|
||||
fMult(direct_ratio, noiseLevel[k]);
|
||||
smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
|
||||
smoothedNoise =
|
||||
(fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
|
||||
fMult(direct_ratio, noiseLevel[k]);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2732,8 +2755,12 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
||||
of the signal and should be carried out with full accuracy
|
||||
(supplying #DFRACT_BITS valid bits).
|
||||
*/
|
||||
signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change);
|
||||
signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change);
|
||||
signalReal =
|
||||
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
signalImag =
|
||||
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
|
||||
index++;
|
||||
|
||||
@@ -2755,8 +2782,12 @@ static void adjustTimeSlotHQ_GainAndNoise(
|
||||
} else {
|
||||
for (k = 0; k < noSubbands; k++) {
|
||||
smoothedGain = gain[k];
|
||||
signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
|
||||
signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
|
||||
signalReal =
|
||||
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
signalImag =
|
||||
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
|
||||
index++;
|
||||
|
||||
@@ -2862,6 +2893,9 @@ static void adjustTimeSlotHQ(
|
||||
int freqInvFlag = (lowSubband & 1);
|
||||
FIXP_DBL sineLevel;
|
||||
int shift;
|
||||
FIXP_DBL max_val_noise = 0, min_val_noise = 0;
|
||||
const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
|
||||
const FIXP_DBL min_val = -max_val;
|
||||
|
||||
*ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
|
||||
*ptrHarmIndex = (harmIndex + 1) & 3;
|
||||
@@ -2877,10 +2911,13 @@ static void adjustTimeSlotHQ(
|
||||
|
||||
filtBufferNoiseShift +=
|
||||
1; /* due to later use of fMultDiv2 instead of fMult */
|
||||
if (filtBufferNoiseShift < 0)
|
||||
if (filtBufferNoiseShift < 0) {
|
||||
shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
|
||||
else
|
||||
} else {
|
||||
shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
|
||||
max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
|
||||
min_val_noise = -max_val_noise;
|
||||
}
|
||||
|
||||
if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
|
||||
for (k = 0; k < noSubbands; k++) {
|
||||
@@ -2896,8 +2933,10 @@ static void adjustTimeSlotHQ(
|
||||
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
|
||||
fMult(direct_ratio, noiseLevel[k]);
|
||||
} else {
|
||||
smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) +
|
||||
fMult(direct_ratio, noiseLevel[k]);
|
||||
smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
|
||||
smoothedNoise =
|
||||
(fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
|
||||
fMult(direct_ratio, noiseLevel[k]);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2905,8 +2944,12 @@ static void adjustTimeSlotHQ(
|
||||
of the signal and should be carried out with full accuracy
|
||||
(supplying #DFRACT_BITS valid bits).
|
||||
*/
|
||||
signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change);
|
||||
signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change);
|
||||
signalReal =
|
||||
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
signalImag =
|
||||
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
|
||||
index++;
|
||||
|
||||
@@ -2959,8 +3002,12 @@ static void adjustTimeSlotHQ(
|
||||
} else {
|
||||
for (k = 0; k < noSubbands; k++) {
|
||||
smoothedGain = gain[k];
|
||||
signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
|
||||
signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
|
||||
signalReal =
|
||||
fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
signalImag =
|
||||
fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
|
||||
<< scale_change;
|
||||
|
||||
index++;
|
||||
|
||||
@@ -3144,6 +3191,11 @@ ResetLimiterBands(
|
||||
return SBRDEC_UNSUPPORTED_CONFIG;
|
||||
}
|
||||
|
||||
/* Restrict maximum value of limiter band table */
|
||||
if (workLimiterBandTable[tempNoLim] > highSubband) {
|
||||
return SBRDEC_UNSUPPORTED_CONFIG;
|
||||
}
|
||||
|
||||
/* Copy limiterbands from working buffer into final destination */
|
||||
for (k = 0; k <= nBands; k++) {
|
||||
limiterBandTable[k] = workLimiterBandTable[k];
|
||||
|
@@ -1014,8 +1014,8 @@ void lppTransposerHBE(
|
||||
pSettings->nCols) +
|
||||
lowBandShift);
|
||||
|
||||
dynamicScale = fixMax(
|
||||
0, dynamicScale - 1); /* one additional bit headroom to prevent -1.0 */
|
||||
dynamicScale =
|
||||
dynamicScale - 1; /* one additional bit headroom to prevent -1.0 */
|
||||
|
||||
/*
|
||||
Scale temporal QMF buffer.
|
||||
@@ -1194,6 +1194,9 @@ void lppTransposerHBE(
|
||||
} else { /* bw <= 0 */
|
||||
|
||||
int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale));
|
||||
dynamicScale +=
|
||||
1; /* prevent negativ scale factor due to 'one additional bit
|
||||
headroom' */
|
||||
|
||||
for (i = startSample; i < stopSample; i++) {
|
||||
FIXP_DBL accu1, accu2;
|
||||
@@ -1210,9 +1213,9 @@ void lppTransposerHBE(
|
||||
dynamicScale;
|
||||
|
||||
qmfBufferReal[i][loBand] =
|
||||
(lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << 1);
|
||||
(lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << (1 + 1));
|
||||
qmfBufferImag[i][loBand] =
|
||||
(lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << 1);
|
||||
(lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << (1 + 1));
|
||||
}
|
||||
} /* bw <= 0 */
|
||||
|
||||
|
@@ -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
|
||||
@@ -534,7 +534,8 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
|
||||
for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) {
|
||||
for (band = sg_borders[ksg]; band < sg_borders[ksg + 1]; band++) {
|
||||
/* The division by 8 == (RATE*lbw) is required algorithmically */
|
||||
E[ksg] += (fPow2Div2(qmfR[band]) + fPow2Div2(qmfI[band])) >> 2;
|
||||
E[ksg] +=
|
||||
((fPow2Div2(qmfR[band]) >> 1) + (fPow2Div2(qmfI[band]) >> 1)) >> 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -542,7 +543,7 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
|
||||
if (E[ksg] > (FIXP_DBL)0) {
|
||||
/* 10/log2(10) = 0.752574989159953 * 2^2 */
|
||||
int exp_log;
|
||||
FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent, &exp_log);
|
||||
FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent + 2, &exp_log);
|
||||
nrg = fMult(nrg, FL2FXCONST_SGL(LOG10FAC));
|
||||
nrg = scaleValue(nrg, exp_log - PVC_ESG_EXP + 2);
|
||||
pEsg[ksg] = fMax(nrg, FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)));
|
||||
@@ -603,22 +604,22 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
|
||||
E_high_exp[ksg] = 0;
|
||||
|
||||
/* residual part */
|
||||
accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP +
|
||||
accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP - 2 +
|
||||
pPvcDynamicData->pScalingCoef[3]);
|
||||
|
||||
/* linear combination of lower grouped energies part */
|
||||
for (kb = 0; kb < PVC_NBLOW; kb++) {
|
||||
predCoeff = (FIXP_SGL)(
|
||||
(SHORT)(SCHAR)pTab1[kb * pPvcDynamicData->nbHigh + ksg] << 8);
|
||||
predCoeff_exp = pPvcDynamicData->pScalingCoef[kb] +
|
||||
1; /* +1 to compensate for Div2 */
|
||||
accu += fMultDiv2(E[kb], predCoeff) << predCoeff_exp;
|
||||
predCoeff_exp = -(pPvcDynamicData->pScalingCoef[kb] + 1 -
|
||||
2); /* +1 to compensate for Div2; -2 for accu */
|
||||
accu += fMultDiv2(E[kb], predCoeff) >> predCoeff_exp;
|
||||
}
|
||||
/* convert back to linear domain */
|
||||
accu = fMult(accu, FL2FXCONST_SGL(LOG10FAC_INV));
|
||||
accu = f2Pow(
|
||||
accu, PVC_ESG_EXP - 1,
|
||||
&predCoeff_exp); /* -1 compensates for exponent of LOG10FAC_INV */
|
||||
accu = f2Pow(accu, PVC_ESG_EXP - 1 + 2,
|
||||
&predCoeff_exp); /* -1 compensates for exponent of
|
||||
LOG10FAC_INV; +2 for accu */
|
||||
predictedEsgSlot[ksg] = accu;
|
||||
E_high_exp[ksg] = predCoeff_exp;
|
||||
if (predCoeff_exp > E_high_exp_max) {
|
||||
@@ -628,8 +629,8 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
|
||||
|
||||
/* rescale output vector according to largest exponent */
|
||||
for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
|
||||
int scale = E_high_exp[ksg] - E_high_exp_max;
|
||||
predictedEsgSlot[ksg] = scaleValue(predictedEsgSlot[ksg], scale);
|
||||
int scale = fMin(E_high_exp_max - E_high_exp[ksg], DFRACT_BITS - 1);
|
||||
predictedEsgSlot[ksg] = predictedEsgSlot[ksg] >> scale;
|
||||
}
|
||||
*predictedEsg_exp = E_high_exp_max;
|
||||
}
|
||||
|
Reference in New Issue
Block a user