aboutsummaryrefslogtreecommitdiffstats
path: root/libSBRdec
diff options
context:
space:
mode:
Diffstat (limited to 'libSBRdec')
-rw-r--r--libSBRdec/include/sbrdecoder.h15
-rw-r--r--libSBRdec/src/HFgen_preFlat.cpp19
-rw-r--r--libSBRdec/src/env_calc.cpp142
-rw-r--r--libSBRdec/src/hbe.cpp6
-rw-r--r--libSBRdec/src/hbe.h10
-rw-r--r--libSBRdec/src/lpp_tran.cpp11
-rw-r--r--libSBRdec/src/pvc_dec.cpp25
-rw-r--r--libSBRdec/src/sbr_crc.cpp192
-rw-r--r--libSBRdec/src/sbr_crc.h138
-rw-r--r--libSBRdec/src/sbr_dec.cpp26
-rw-r--r--libSBRdec/src/sbr_dec.h11
-rw-r--r--libSBRdec/src/sbr_ram.cpp5
-rw-r--r--libSBRdec/src/sbr_ram.h5
-rw-r--r--libSBRdec/src/sbrdec_freq_sca.cpp7
-rw-r--r--libSBRdec/src/sbrdecoder.cpp133
15 files changed, 234 insertions, 511 deletions
diff --git a/libSBRdec/include/sbrdecoder.h b/libSBRdec/include/sbrdecoder.h
index cc55572..c09c985 100644
--- a/libSBRdec/include/sbrdecoder.h
+++ b/libSBRdec/include/sbrdecoder.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
@@ -361,15 +361,20 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
* error (0: core decoder found errors, 1: no errors).
* \param psDecoded Pointer to a buffer holding a flag. Input: PS is
* possible, Output: PS has been rendered.
+ * \param inDataHeadroom Headroom of the SBR input time signal to prevent
+ * clipping.
+ * \param outDataHeadroom Pointer to headroom of the SBR output time signal to
+ * prevent clipping.
*
* \return Error code.
*/
-SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input,
- INT_PCM *timeData, const int timeDataSize,
- int *numChannels, int *sampleRate,
+SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, LONG *input, LONG *timeData,
+ const int timeDataSize, int *numChannels,
+ int *sampleRate,
const FDK_channelMapDescr *const mapDescr,
const int mapIdx, const int coreDecodedOk,
- UCHAR *psDecoded);
+ UCHAR *psDecoded, const INT inDataHeadroom,
+ INT *outDataHeadroom);
/**
* \brief Close SBR decoder instance and free memory.
diff --git a/libSBRdec/src/HFgen_preFlat.cpp b/libSBRdec/src/HFgen_preFlat.cpp
index 96adbb9..ad4caba 100644
--- a/libSBRdec/src/HFgen_preFlat.cpp
+++ b/libSBRdec/src/HFgen_preFlat.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
@@ -897,30 +897,31 @@ void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal,
for (i = startSample; i < stopSample; i++) {
maxVal |=
(FIXP_DBL)((LONG)(sourceBufferReal[i][loBand]) ^
- ((LONG)sourceBufferReal[i][loBand] >> (SAMPLE_BITS - 1)));
+ ((LONG)sourceBufferReal[i][loBand] >> (DFRACT_BITS - 1)));
maxVal |=
(FIXP_DBL)((LONG)(sourceBufferImag[i][loBand]) ^
- ((LONG)sourceBufferImag[i][loBand] >> (SAMPLE_BITS - 1)));
+ ((LONG)sourceBufferImag[i][loBand] >> (DFRACT_BITS - 1)));
}
if (maxVal != FL2FX_DBL(0.0f)) {
- reserve = fixMax(0, CntLeadingZeros(maxVal) - 2);
+ reserve = CntLeadingZeros(maxVal) - 2;
}
nrg_ov = nrg = (FIXP_DBL)0;
if (scale_nrg_ov > -31) {
for (i = startSample; i < overlap; i++) {
- nrg_ov += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) +
- fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >>
- sum_scale_ov;
+ nrg_ov +=
+ (fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) +
+ fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >>
+ sum_scale_ov;
}
} else {
scale_nrg_ov = 0;
}
if (scale_nrg > -31) {
for (i = overlap; i < stopSample; i++) {
- nrg += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) +
- fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >>
+ nrg += (fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) +
+ fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >>
sum_scale;
}
} else {
diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp
index 1242833..0b2f651 100644
--- a/libSBRdec/src/env_calc.cpp
+++ b/libSBRdec/src/env_calc.cpp
@@ -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];
@@ -699,20 +702,11 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
gain_sf[i] += gamma_sf + 1; /* +1 because of fMultDiv2() */
/* set gain to at least 0.2f */
- FIXP_DBL point_two = FL2FXCONST_DBL(0.8f); /* scaled up by 2 */
- int point_two_sf = -2;
-
- FIXP_DBL tmp = gain[i];
- if (point_two_sf < gain_sf[i]) {
- point_two >>= gain_sf[i] - point_two_sf;
- } else {
- tmp >>= point_two_sf - gain_sf[i];
- }
-
/* limit and calculate gain[i]^2 too */
FIXP_DBL gain_pow2;
int gain_pow2_sf;
- if (tmp < point_two) {
+
+ if (fIsLessThan(gain[i], gain_sf[i], FL2FXCONST_DBL(0.2f), 0)) {
gain[i] = FL2FXCONST_DBL(0.8f);
gain_sf[i] = -2;
gain_pow2 = FL2FXCONST_DBL(0.64f);
@@ -739,7 +733,8 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf);
total_power_high_after_sf = new_summand_sf;
} else if (new_summand_sf < total_power_high_after_sf) {
- subsample_power_high[i] >>= total_power_high_after_sf - new_summand_sf;
+ subsample_power_high[i] >>=
+ fMin(DFRACT_BITS - 1, total_power_high_after_sf - new_summand_sf);
}
total_power_high_after += subsample_power_high[i] >> preShift2;
}
@@ -985,7 +980,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
@@ -1005,7 +1001,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
@@ -1031,7 +1027,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 */
@@ -1477,7 +1473,7 @@ void calculateSbrEnvelope(
for (k = 0; k < noSubbands; k++) {
int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1);
- pNrgs->nrgGain[k] >>= sc;
+ pNrgs->nrgGain[k] >>= fixMin(sc, DFRACT_BITS - 1);
pNrgs->nrgGain_e[k] += sc;
}
@@ -1485,7 +1481,7 @@ void calculateSbrEnvelope(
for (k = 0; k < noSubbands; k++) {
int sc =
scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1);
- h_sbr_cal_env->filtBuffer[k] >>= sc;
+ h_sbr_cal_env->filtBuffer[k] >>= fixMin(sc, DFRACT_BITS - 1);
}
}
@@ -1576,12 +1572,13 @@ void calculateSbrEnvelope(
FDK_ASSERT(!iTES_enable); /* not supported */
if (flags & SBRDEC_ELD_GRID) {
/* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */
- adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband], pNrgs,
- &h_sbr_cal_env->harmIndex, lowSubband,
- noSubbands,
- fMin(scale_change, DFRACT_BITS - 1),
- noNoiseFlag, &h_sbr_cal_env->phaseIndex,
- EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale);
+ adjustTimeSlot_EldGrid(
+ &analysBufferReal[j][lowSubband], pNrgs,
+ &h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
+ fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag,
+ &h_sbr_cal_env->phaseIndex,
+ fMax(EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale,
+ -(DFRACT_BITS - 1)));
} else {
adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs,
&h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
@@ -1830,7 +1827,8 @@ static void equalizeFiltBufferExp(
diff = (int)(nrgGain_e[band] - filtBuffer_e[band]);
if (diff > 0) {
filtBuffer[band] >>=
- diff; /* Compensate for the scale change by shifting the mantissa. */
+ fMin(diff, DFRACT_BITS - 1); /* Compensate for the scale change by
+ shifting the mantissa. */
filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */
} else if (diff < 0) {
/* The buffered gains seem to be larger, but maybe there
@@ -1850,8 +1848,8 @@ static void equalizeFiltBufferExp(
filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */
/* For the remaining difference, change the new gain value */
- diff = fixMin(-(reserve + diff), DFRACT_BITS - 1);
- nrgGain[band] >>= diff;
+ diff = -(reserve + diff);
+ nrgGain[band] >>= fMin(diff, DFRACT_BITS - 1);
nrgGain_e[band] += diff;
}
}
@@ -2423,6 +2421,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]),
@@ -2435,7 +2436,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 +=
@@ -2469,7 +2471,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 +=
@@ -2509,6 +2512,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))
@@ -2524,7 +2529,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);
@@ -2552,10 +2558,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;
@@ -2586,7 +2592,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;
@@ -2599,7 +2607,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++;
@@ -2627,7 +2636,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];
@@ -2696,6 +2706,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);
@@ -2705,6 +2718,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)) {
@@ -2720,8 +2735,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]);
}
/*
@@ -2729,8 +2746,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++;
@@ -2752,8 +2773,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++;
@@ -2859,6 +2884,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;
@@ -2874,10 +2902,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++) {
@@ -2893,8 +2924,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]);
}
/*
@@ -2902,8 +2935,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++;
@@ -2956,8 +2993,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++;
@@ -3141,6 +3182,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];
diff --git a/libSBRdec/src/hbe.cpp b/libSBRdec/src/hbe.cpp
index 3310dcd..77cb8af 100644
--- a/libSBRdec/src/hbe.cpp
+++ b/libSBRdec/src/hbe.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
@@ -957,7 +957,7 @@ QmfTransposerCreate(HANDLE_HBE_TRANSPOSER* hQmfTransposer, const int frameSize,
hQmfTran->qmfOutBufSize = 2 * (hQmfTran->noCols / 2 + QMF_WIN_LEN - 1);
hQmfTran->inBuf_F =
- (INT_PCM*)FDKcalloc(QMF_SYNTH_CHANNELS + 20 + 1, sizeof(INT_PCM));
+ (LONG*)FDKcalloc(QMF_SYNTH_CHANNELS + 20 + 1, sizeof(LONG));
/* buffered time signal needs to be delayed by synthesis_size; max
* synthesis_size = 20; */
if (hQmfTran->inBuf_F == NULL) {
@@ -1339,7 +1339,7 @@ static void addHighBandPart(FIXP_DBL g_r_m, FIXP_DBL g_i_m, INT g_e,
g_r_m = fMultDiv2(tmp_r, factor_m) << shift;
g_i_m = fMultDiv2(tmp_i, factor_m) << shift;
g_e = scale_factor_hbe - (g_e + factor_e + gammaCenter_e + add);
- fMax((INT)0, g_e);
+ g_e = fMax((INT)0, g_e);
*qmfHBEBufReal_F += g_r_m >> g_e;
*qmfHBEBufImag_F += g_i_m >> g_e;
}
diff --git a/libSBRdec/src/hbe.h b/libSBRdec/src/hbe.h
index fdffe1e..3556783 100644
--- a/libSBRdec/src/hbe.h
+++ b/libSBRdec/src/hbe.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
@@ -132,6 +132,9 @@ typedef enum {
} KEEP_STATES_SYNCED_MODE;
struct hbeTransposer {
+ FIXP_DBL anaQmfStates[HBE_QMF_FILTER_STATE_ANA_SIZE];
+ FIXP_QSS synQmfStates[HBE_QMF_FILTER_STATE_SYN_SIZE];
+
int xOverQmf[MAX_NUM_PATCHES_HBE];
int maxStretch;
@@ -144,7 +147,7 @@ struct hbeTransposer {
int stopBand;
int bSbr41;
- INT_PCM *inBuf_F;
+ LONG *inBuf_F;
FIXP_DBL **qmfInBufReal_F;
FIXP_DBL **qmfInBufImag_F;
@@ -156,9 +159,6 @@ struct hbeTransposer {
FIXP_DBL const *synthesisQmfPreModCos_F;
FIXP_DBL const *synthesisQmfPreModSin_F;
- FIXP_QAS anaQmfStates[HBE_QMF_FILTER_STATE_ANA_SIZE];
- FIXP_QSS synQmfStates[HBE_QMF_FILTER_STATE_SYN_SIZE];
-
FIXP_DBL **qmfHBEBufReal_F;
FIXP_DBL **qmfHBEBufImag_F;
diff --git a/libSBRdec/src/lpp_tran.cpp b/libSBRdec/src/lpp_tran.cpp
index 6acb626..93e1158 100644
--- a/libSBRdec/src/lpp_tran.cpp
+++ b/libSBRdec/src/lpp_tran.cpp
@@ -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 */
diff --git a/libSBRdec/src/pvc_dec.cpp b/libSBRdec/src/pvc_dec.cpp
index b477122..e1e3c2c 100644
--- a/libSBRdec/src/pvc_dec.cpp
+++ b/libSBRdec/src/pvc_dec.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
@@ -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;
}
diff --git a/libSBRdec/src/sbr_crc.cpp b/libSBRdec/src/sbr_crc.cpp
deleted file mode 100644
index ba0fd05..0000000
--- a/libSBRdec/src/sbr_crc.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/* -----------------------------------------------------------------------------
-Software License for The Fraunhofer FDK AAC Codec Library for Android
-
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
-Forschung e.V. All rights reserved.
-
- 1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
-that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
-scheme for digital audio. This FDK AAC Codec software is intended to be used on
-a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
-general perceptual audio codecs. AAC-ELD is considered the best-performing
-full-bandwidth communications codec by independent studies and is widely
-deployed. AAC has been standardized by ISO and IEC as part of the MPEG
-specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including
-those of Fraunhofer) may be obtained through Via Licensing
-(www.vialicensing.com) or through the respective patent owners individually for
-the purpose of encoding or decoding bit streams in products that are compliant
-with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
-Android devices already license these patent claims through Via Licensing or
-directly from the patent owners, and therefore FDK AAC Codec software may
-already be covered under those patent licenses when it is used for those
-licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions
-with enhanced sound quality, are also available from Fraunhofer. Users are
-encouraged to check the Fraunhofer website for additional applications
-information and documentation.
-
-2. COPYRIGHT LICENSE
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted without payment of copyright license fees provided that you
-satisfy the following conditions:
-
-You must retain the complete text of this software license in redistributions of
-the FDK AAC Codec or your modifications thereto in source code form.
-
-You must retain the complete text of this software license in the documentation
-and/or other materials provided with redistributions of the FDK AAC Codec or
-your modifications thereto in binary form. You must make available free of
-charge copies of the complete source code of the FDK AAC Codec and your
-modifications thereto to recipients of copies in binary form.
-
-The name of Fraunhofer may not be used to endorse or promote products derived
-from this library without prior written permission.
-
-You may not charge copyright license fees for anyone to use, copy or distribute
-the FDK AAC Codec software or your modifications thereto.
-
-Your modified versions of the FDK AAC Codec must carry prominent notices stating
-that you changed the software and the date of any change. For modified versions
-of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
-must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
-AAC Codec Library for Android."
-
-3. NO PATENT LICENSE
-
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
-limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
-Fraunhofer provides no warranty of patent non-infringement with respect to this
-software.
-
-You may use this FDK AAC Codec software or modifications thereto only for
-purposes that are authorized by appropriate patent licenses.
-
-4. DISCLAIMER
-
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
-holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
-including but not limited to the implied warranties of merchantability and
-fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
-or consequential damages, including but not limited to procurement of substitute
-goods or services; loss of use, data, or profits, or business interruption,
-however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of
-this software, even if advised of the possibility of such damage.
-
-5. CONTACT INFORMATION
-
-Fraunhofer Institute for Integrated Circuits IIS
-Attention: Audio and Multimedia Departments - FDK AAC LL
-Am Wolfsmantel 33
-91058 Erlangen, Germany
-
-www.iis.fraunhofer.de/amm
-amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------ */
-
-/**************************** SBR decoder library ******************************
-
- Author(s):
-
- Description:
-
-*******************************************************************************/
-
-/*!
- \file
- \brief CRC check coutines
-*/
-
-#include "sbr_crc.h"
-
-#include "FDK_bitstream.h"
-#include "transcendent.h"
-
-#define MAXCRCSTEP 16
-#define MAXCRCSTEP_LD 4
-
-/*!
- \brief crc calculation
-*/
-static ULONG calcCRC(HANDLE_CRC hCrcBuf, ULONG bValue, int nBits) {
- int i;
- ULONG bMask = (1UL << (nBits - 1));
-
- for (i = 0; i < nBits; i++, bMask >>= 1) {
- USHORT flag = (hCrcBuf->crcState & hCrcBuf->crcMask) ? 1 : 0;
- USHORT flag1 = (bMask & bValue) ? 1 : 0;
-
- flag ^= flag1;
- hCrcBuf->crcState <<= 1;
- if (flag) hCrcBuf->crcState ^= hCrcBuf->crcPoly;
- }
-
- return (hCrcBuf->crcState);
-}
-
-/*!
- \brief crc
-*/
-static int getCrc(HANDLE_FDK_BITSTREAM hBs, ULONG NrBits) {
- int i;
- CRC_BUFFER CrcBuf;
-
- CrcBuf.crcState = SBR_CRC_START;
- CrcBuf.crcPoly = SBR_CRC_POLY;
- CrcBuf.crcMask = SBR_CRC_MASK;
-
- int CrcStep = NrBits >> MAXCRCSTEP_LD;
-
- int CrcNrBitsRest = (NrBits - CrcStep * MAXCRCSTEP);
- ULONG bValue;
-
- for (i = 0; i < CrcStep; i++) {
- bValue = FDKreadBits(hBs, MAXCRCSTEP);
- calcCRC(&CrcBuf, bValue, MAXCRCSTEP);
- }
-
- bValue = FDKreadBits(hBs, CrcNrBitsRest);
- calcCRC(&CrcBuf, bValue, CrcNrBitsRest);
-
- return (CrcBuf.crcState & SBR_CRC_RANGE);
-}
-
-/*!
- \brief crc interface
- \return 1: CRC OK, 0: CRC check failure
-*/
-int SbrCrcCheck(HANDLE_FDK_BITSTREAM hBs, /*!< handle to bit-buffer */
- LONG NrBits) /*!< max. CRC length */
-{
- int crcResult = 1;
- ULONG NrCrcBits;
- ULONG crcCheckResult;
- LONG NrBitsAvailable;
- ULONG crcCheckSum;
-
- crcCheckSum = FDKreadBits(hBs, 10);
-
- NrBitsAvailable = FDKgetValidBits(hBs);
- if (NrBitsAvailable <= 0) {
- return 0;
- }
-
- NrCrcBits = fixMin((INT)NrBits, (INT)NrBitsAvailable);
-
- crcCheckResult = getCrc(hBs, NrCrcBits);
- FDKpushBack(hBs, (NrBitsAvailable - FDKgetValidBits(hBs)));
-
- if (crcCheckResult != crcCheckSum) {
- crcResult = 0;
- }
-
- return (crcResult);
-}
diff --git a/libSBRdec/src/sbr_crc.h b/libSBRdec/src/sbr_crc.h
deleted file mode 100644
index 9633717..0000000
--- a/libSBRdec/src/sbr_crc.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/* -----------------------------------------------------------------------------
-Software License for The Fraunhofer FDK AAC Codec Library for Android
-
-© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
-Forschung e.V. All rights reserved.
-
- 1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
-that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
-scheme for digital audio. This FDK AAC Codec software is intended to be used on
-a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
-general perceptual audio codecs. AAC-ELD is considered the best-performing
-full-bandwidth communications codec by independent studies and is widely
-deployed. AAC has been standardized by ISO and IEC as part of the MPEG
-specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including
-those of Fraunhofer) may be obtained through Via Licensing
-(www.vialicensing.com) or through the respective patent owners individually for
-the purpose of encoding or decoding bit streams in products that are compliant
-with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
-Android devices already license these patent claims through Via Licensing or
-directly from the patent owners, and therefore FDK AAC Codec software may
-already be covered under those patent licenses when it is used for those
-licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions
-with enhanced sound quality, are also available from Fraunhofer. Users are
-encouraged to check the Fraunhofer website for additional applications
-information and documentation.
-
-2. COPYRIGHT LICENSE
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted without payment of copyright license fees provided that you
-satisfy the following conditions:
-
-You must retain the complete text of this software license in redistributions of
-the FDK AAC Codec or your modifications thereto in source code form.
-
-You must retain the complete text of this software license in the documentation
-and/or other materials provided with redistributions of the FDK AAC Codec or
-your modifications thereto in binary form. You must make available free of
-charge copies of the complete source code of the FDK AAC Codec and your
-modifications thereto to recipients of copies in binary form.
-
-The name of Fraunhofer may not be used to endorse or promote products derived
-from this library without prior written permission.
-
-You may not charge copyright license fees for anyone to use, copy or distribute
-the FDK AAC Codec software or your modifications thereto.
-
-Your modified versions of the FDK AAC Codec must carry prominent notices stating
-that you changed the software and the date of any change. For modified versions
-of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
-must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
-AAC Codec Library for Android."
-
-3. NO PATENT LICENSE
-
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
-limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
-Fraunhofer provides no warranty of patent non-infringement with respect to this
-software.
-
-You may use this FDK AAC Codec software or modifications thereto only for
-purposes that are authorized by appropriate patent licenses.
-
-4. DISCLAIMER
-
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
-holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
-including but not limited to the implied warranties of merchantability and
-fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
-or consequential damages, including but not limited to procurement of substitute
-goods or services; loss of use, data, or profits, or business interruption,
-however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of
-this software, even if advised of the possibility of such damage.
-
-5. CONTACT INFORMATION
-
-Fraunhofer Institute for Integrated Circuits IIS
-Attention: Audio and Multimedia Departments - FDK AAC LL
-Am Wolfsmantel 33
-91058 Erlangen, Germany
-
-www.iis.fraunhofer.de/amm
-amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------ */
-
-/**************************** SBR decoder library ******************************
-
- Author(s):
-
- Description:
-
-*******************************************************************************/
-
-/*!
- \file
- \brief CRC checking routines
-*/
-#ifndef SBR_CRC_H
-#define SBR_CRC_H
-
-#include "sbrdecoder.h"
-
-#include "FDK_bitstream.h"
-
-/* some useful crc polynoms:
-
-crc5: x^5+x^4+x^2+x^1+1
-crc6: x^6+x^5+x^3+x^2+x+1
-crc7: x^7+x^6+x^2+1
-crc8: x^8+x^2+x+x+1
-*/
-
-/* default SBR CRC */ /* G(x) = x^10 + x^9 + x^5 + x^4 + x + 1 */
-#define SBR_CRC_POLY 0x0233
-#define SBR_CRC_MASK 0x0200
-#define SBR_CRC_START 0x0000
-#define SBR_CRC_RANGE 0x03FF
-
-typedef struct {
- USHORT crcState;
- USHORT crcMask;
- USHORT crcPoly;
-} CRC_BUFFER;
-
-typedef CRC_BUFFER *HANDLE_CRC;
-
-int SbrCrcCheck(HANDLE_FDK_BITSTREAM hBitBuf, LONG NrCrcBits);
-
-#endif
diff --git a/libSBRdec/src/sbr_dec.cpp b/libSBRdec/src/sbr_dec.cpp
index 30611e7..b1fb0da 100644
--- a/libSBRdec/src/sbr_dec.cpp
+++ b/libSBRdec/src/sbr_dec.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
@@ -259,17 +259,18 @@ static void copyHarmonicSpectrum(int *xOverQmf, FIXP_DBL **qmfReal,
void sbr_dec(
HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
- INT_PCM *timeIn, /*!< pointer to input time signal */
- INT_PCM *timeOut, /*!< pointer to output time signal */
+ LONG *timeIn, /*!< pointer to input time signal */
+ LONG *timeOut, /*!< pointer to output time signal */
HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */
- INT_PCM *timeOutRight, /*!< pointer to output time signal */
+ LONG *timeOutRight, /*!< pointer to output time signal */
const int strideOut, /*!< Time data traversal strideOut */
HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
HANDLE_SBR_PREV_FRAME_DATA
hPrevFrameData, /*!< Some control data of last frame */
const int applyProcessing, /*!< Flag for SBR operation */
- HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize) {
+ HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize,
+ const INT sbrInDataHeadroom) {
int i, slot, reserve;
int saveLbScale;
int lastSlotOffs;
@@ -278,7 +279,7 @@ void sbr_dec(
/* temporary pointer / variable for QMF;
required as we want to use temporary buffer
creating one frame delay for HBE in LP mode */
- INT_PCM *pTimeInQmf = timeIn;
+ LONG *pTimeInQmf = timeIn;
/* Number of QMF timeslots in the overlap buffer: */
int ov_len = hSbrDec->LppTrans.pSettings->overlap;
@@ -341,8 +342,8 @@ void sbr_dec(
} else {
C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * (64));
qmfAnalysisFiltering(&hSbrDec->qmfDomainInCh->fb, pReal, pImag,
- &hSbrDec->qmfDomainInCh->scaling, pTimeInQmf, 0, 1,
- qmfTemp);
+ &hSbrDec->qmfDomainInCh->scaling, pTimeInQmf,
+ 0 + sbrInDataHeadroom, 1, qmfTemp);
C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * (64));
}
@@ -658,7 +659,7 @@ void sbr_dec(
if (!(flags & SBRDEC_PS_DECODED)) {
if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
- int outScalefactor = 0;
+ int outScalefactor = -(8);
if (h_ps_d != NULL) {
h_ps_d->procFrameBased = 1; /* we here do frame based processing */
@@ -743,6 +744,7 @@ void sbr_dec(
*/
FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <=
QMF_MAX_SYNTHESIS_BANDS);
+ qmfChangeOutScalefactor(synQmfRight, -(8));
FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates,
9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis *
sizeof(FIXP_QSS));
@@ -814,7 +816,8 @@ void sbr_dec(
: scaleFactorLowBand_no_ov,
scaleFactorHighBand, synQmf->lsb, synQmf->usb);
- outScalefactorL = outScalefactorR = 1; /* psDiffScale! (MPEG-PS) */
+ outScalefactorL = outScalefactorR =
+ 1 + sbrInDataHeadroom; /* psDiffScale! (MPEG-PS) */
}
sbrDecoder_drcApplySlot(/* right channel */
@@ -831,6 +834,9 @@ void sbr_dec(
outScalefactorL += maxShift;
if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
+ qmfChangeOutScalefactor(synQmf, -(8));
+ qmfChangeOutScalefactor(synQmfRight, -(8));
+
qmfSynthesisFilteringSlot(
synQmfRight, rQmfReal, /* QMF real buffer */
rQmfImag, /* QMF imag buffer */
diff --git a/libSBRdec/src/sbr_dec.h b/libSBRdec/src/sbr_dec.h
index 156da03..eb9c394 100644
--- a/libSBRdec/src/sbr_dec.h
+++ b/libSBRdec/src/sbr_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
@@ -176,17 +176,18 @@ typedef SBR_CHANNEL *HANDLE_SBR_CHANNEL;
void sbr_dec(
HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
- INT_PCM *timeIn, /*!< pointer to input time signal */
- INT_PCM *timeOut, /*!< pointer to output time signal */
+ LONG *timeIn, /*!< pointer to input time signal */
+ LONG *timeOut, /*!< pointer to output time signal */
HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */
- INT_PCM *timeOutRight, /*!< pointer to output time signal */
+ LONG *timeOutRight, /*!< pointer to output time signal */
INT strideOut, /*!< Time data traversal strideOut */
HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
HANDLE_SBR_PREV_FRAME_DATA
hPrevFrameData, /*!< Some control data of last frame */
const int applyProcessing, /*!< Flag for SBR operation */
- HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize);
+ HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize,
+ const INT sbrInDataHeadroom);
SBR_ERROR
createSbrDec(SBR_CHANNEL *hSbrChannel, HANDLE_SBR_HEADER_DATA hHeaderData,
diff --git a/libSBRdec/src/sbr_ram.cpp b/libSBRdec/src/sbr_ram.cpp
index 8b35fd2..a759d71 100644
--- a/libSBRdec/src/sbr_ram.cpp
+++ b/libSBRdec/src/sbr_ram.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
@@ -109,9 +109,6 @@ amm-info@iis.fraunhofer.de
#include "sbr_ram.h"
-#define WORKBUFFER1_TAG 2
-#define WORKBUFFER2_TAG 3
-
/*!
\name StaticSbrData
diff --git a/libSBRdec/src/sbr_ram.h b/libSBRdec/src/sbr_ram.h
index e00f8b5..452f835 100644
--- a/libSBRdec/src/sbr_ram.h
+++ b/libSBRdec/src/sbr_ram.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
@@ -170,6 +170,9 @@ struct SBR_DECODER_INSTANCE {
flushed consecutively. */
UINT flags;
+
+ INT sbrInDataHeadroom; /* Headroom of the SBR input time signal to prevent
+ clipping */
};
H_ALLOC_MEM(Ram_SbrDecElement, SBR_DECODER_ELEMENT)
diff --git a/libSBRdec/src/sbrdec_freq_sca.cpp b/libSBRdec/src/sbrdec_freq_sca.cpp
index 165f94b..e187656 100644
--- a/libSBRdec/src/sbrdec_freq_sca.cpp
+++ b/libSBRdec/src/sbrdec_freq_sca.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
@@ -230,6 +230,8 @@ static UCHAR getStopBand(
}
}
+ stopMin = fMin(stopMin, 64);
+
/*
Choose a stop band between k1 and 64 depending on stopFreq (0..13),
based on a logarithmic scale.
@@ -523,7 +525,8 @@ static FIXP_SGL calcFactorPerBand(int k_start, int k_stop, int num_bands) {
step = FL2FXCONST_DBL(0.0f);
}
}
- return FX_DBL2FX_SGL(bandfactor << 1);
+ return (bandfactor >= FL2FXCONST_DBL(0.5)) ? (FIXP_SGL)MAXVAL_SGL
+ : FX_DBL2FX_SGL(bandfactor << 1);
}
/*!
diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp
index c827ced..b101a4a 100644
--- a/libSBRdec/src/sbrdecoder.cpp
+++ b/libSBRdec/src/sbrdecoder.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
@@ -143,24 +143,22 @@ amm-info@iis.fraunhofer.de
#include "env_extr.h"
#include "sbr_dec.h"
#include "env_dec.h"
-#include "sbr_crc.h"
+#include "FDK_crc.h"
#include "sbr_ram.h"
#include "sbr_rom.h"
#include "lpp_tran.h"
#include "transcendent.h"
-#include "FDK_crc.h"
-
#include "sbrdec_drc.h"
#include "psbitdec.h"
/* Decoder library info */
#define SBRDECODER_LIB_VL0 3
-#define SBRDECODER_LIB_VL1 0
+#define SBRDECODER_LIB_VL1 1
#define SBRDECODER_LIB_VL2 0
#define SBRDECODER_LIB_TITLE "SBR Decoder"
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
#define SBRDECODER_LIB_BUILD_DATE ""
#define SBRDECODER_LIB_BUILD_TIME ""
#else
@@ -619,10 +617,6 @@ SBR_ERROR sbrDecoder_InitElement(
self->numSbrChannels -= self->pSbrElement[elementIndex]->nChannels;
}
- /* Save element ID for sanity checks and to have a fallback for concealment.
- */
- self->pSbrElement[elementIndex]->elementID = elementID;
-
/* Determine amount of channels for this element */
switch (elementID) {
case ID_NONE:
@@ -655,12 +649,16 @@ SBR_ERROR sbrDecoder_InitElement(
}
/* Sanity check to avoid memory leaks */
- if (elChannels < self->pSbrElement[elementIndex]->nChannels) {
+ if (elChannels < self->pSbrElement[elementIndex]->nChannels ||
+ (self->numSbrChannels + elChannels) > (8) + (1)) {
self->numSbrChannels += self->pSbrElement[elementIndex]->nChannels;
sbrError = SBRDEC_PARSE_ERROR;
goto bail;
}
+ /* Save element ID for sanity checks and to have a fallback for concealment.
+ */
+ self->pSbrElement[elementIndex]->elementID = elementID;
self->pSbrElement[elementIndex]->nChannels = elChannels;
for (ch = 0; ch < elChannels; ch++) {
@@ -1134,18 +1132,22 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT;
INT startPos = FDKgetValidBits(hBs);
- INT CRCLen = 0;
+ FDK_CRCINFO crcInfo;
+ INT crcReg = 0;
+ USHORT sbrCrc = 0;
+ UINT crcPoly;
+ UINT crcStartValue = 0;
+ UINT crcLen;
+
HANDLE_FDK_BITSTREAM hBsOriginal = hBs;
FDK_BITSTREAM bsBwd;
- FDK_CRCINFO crcInfo;
- INT crcReg = 0;
- USHORT drmSbrCrc = 0;
const int fGlobalIndependencyFlag = acFlags & AC_INDEP;
const int bs_pvc = acElFlags[elementIndex] & AC_EL_USAC_PVC;
const int bs_interTes = acElFlags[elementIndex] & AC_EL_USAC_ITES;
int stereo;
int fDoDecodeSbrData = 1;
+ int alignBits = 0;
int lastSlot, lastHdrSlot = 0, thisHdrSlot = 0;
@@ -1277,27 +1279,23 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
if (fDoDecodeSbrData) {
if (crcFlag) {
switch (self->coreCodec) {
- case AOT_ER_AAC_ELD:
- FDKpushFor(hBs, 10);
- /* check sbrcrc later: we don't know the payload length now */
- break;
case AOT_DRM_AAC:
case AOT_DRM_SURROUND:
- drmSbrCrc = (USHORT)FDKreadBits(hBs, 8);
- /* Setup CRC decoder */
- FDKcrcInit(&crcInfo, 0x001d, 0xFFFF, 8);
- /* Start CRC region */
- crcReg = FDKcrcStartReg(&crcInfo, hBs, 0);
+ crcPoly = 0x001d;
+ crcLen = 8;
+ crcStartValue = 0x000000ff;
break;
default:
- CRCLen = bsPayLen - 10; /* change: 0 => i */
- if (CRCLen < 0) {
- fDoDecodeSbrData = 0;
- } else {
- fDoDecodeSbrData = SbrCrcCheck(hBs, CRCLen);
- }
+ crcPoly = 0x0633;
+ crcLen = 10;
+ crcStartValue = 0x00000000;
break;
}
+ sbrCrc = (USHORT)FDKreadBits(hBs, crcLen);
+ /* Setup CRC decoder */
+ FDKcrcInit(&crcInfo, crcPoly, crcStartValue, crcLen);
+ /* Start CRC region */
+ crcReg = FDKcrcStartReg(&crcInfo, hBs, 0);
}
} /* if (fDoDecodeSbrData) */
@@ -1450,35 +1448,6 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
valBits = (INT)FDKgetValidBits(hBs);
}
- if (crcFlag) {
- switch (self->coreCodec) {
- case AOT_ER_AAC_ELD: {
- /* late crc check for eld */
- INT payloadbits =
- (INT)startPos - (INT)FDKgetValidBits(hBs) - startPos;
- INT crcLen = payloadbits - 10;
- FDKpushBack(hBs, payloadbits);
- fDoDecodeSbrData = SbrCrcCheck(hBs, crcLen);
- FDKpushFor(hBs, crcLen);
- } break;
- case AOT_DRM_AAC:
- case AOT_DRM_SURROUND:
- /* End CRC region */
- FDKcrcEndReg(&crcInfo, hBs, crcReg);
- /* Check CRC */
- if ((FDKcrcGetCRC(&crcInfo) ^ 0xFF) != drmSbrCrc) {
- fDoDecodeSbrData = 0;
- if (headerStatus != HEADER_NOT_PRESENT) {
- headerStatus = HEADER_ERROR;
- hSbrHeader->syncState = SBR_NOT_INITIALIZED;
- }
- }
- break;
- default:
- break;
- }
- }
-
/* sanity check of remaining bits */
if (valBits < 0) {
fDoDecodeSbrData = 0;
@@ -1489,7 +1458,7 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
case AOT_AAC_LC: {
/* This sanity check is only meaningful with General Audio
* bitstreams */
- int alignBits = valBits & 0x7;
+ alignBits = valBits & 0x7;
if (valBits > alignBits) {
fDoDecodeSbrData = 0;
@@ -1508,6 +1477,20 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
errorStatus = SBRDEC_PARSE_ERROR;
}
+ if (crcFlag && (hSbrHeader->syncState >= SBR_HEADER) && fDoDecodeSbrData) {
+ FDKpushFor(hBs, alignBits);
+ FDKcrcEndReg(&crcInfo, hBs, crcReg); /* End CRC region */
+ FDKpushBack(hBs, alignBits);
+ /* Check CRC */
+ if ((FDKcrcGetCRC(&crcInfo) ^ crcStartValue) != sbrCrc) {
+ fDoDecodeSbrData = 0;
+ if (headerStatus != HEADER_NOT_PRESENT) {
+ headerStatus = HEADER_ERROR;
+ hSbrHeader->syncState = SBR_NOT_INITIALIZED;
+ }
+ }
+ }
+
if (!fDoDecodeSbrData) {
/* Set error flag for this slot to trigger concealment */
setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR);
@@ -1587,10 +1570,10 @@ bail:
* \return SBRDEC_OK if successfull, else error code
*/
static SBR_ERROR sbrDecoder_DecodeElement(
- HANDLE_SBRDECODER self, QDOM_PCM *input, INT_PCM *timeData,
- const int timeDataSize, const FDK_channelMapDescr *const mapDescr,
- const int mapIdx, int channelIndex, const int elementIndex,
- const int numInChannels, int *numOutChannels, const int psPossible) {
+ HANDLE_SBRDECODER self, LONG *input, LONG *timeData, const int timeDataSize,
+ const FDK_channelMapDescr *const mapDescr, const int mapIdx,
+ int channelIndex, const int elementIndex, const int numInChannels,
+ int *numOutChannels, const int psPossible) {
SBR_DECODER_ELEMENT *hSbrElement = self->pSbrElement[elementIndex];
HANDLE_SBR_CHANNEL *pSbrChannel =
self->pSbrElement[elementIndex]->pSbrChannel;
@@ -1760,7 +1743,7 @@ static SBR_ERROR sbrDecoder_DecodeElement(
timeData + offset1, strideOut, hSbrHeader, hFrameDataLeft,
&pSbrChannel[0]->prevFrameData,
(hSbrHeader->syncState == SBR_ACTIVE), h_ps_d, self->flags,
- codecFrameSize);
+ codecFrameSize, self->sbrInDataHeadroom);
if (stereo) {
/* Process right channel */
@@ -1768,7 +1751,7 @@ static SBR_ERROR sbrDecoder_DecodeElement(
timeData + offset1, NULL, NULL, strideOut, hSbrHeader,
hFrameDataRight, &pSbrChannel[1]->prevFrameData,
(hSbrHeader->syncState == SBR_ACTIVE), NULL, self->flags,
- codecFrameSize);
+ codecFrameSize, self->sbrInDataHeadroom);
}
C_ALLOC_SCRATCH_END(pPsScratch, struct PS_DEC_COEFFICIENTS, 1)
@@ -1788,14 +1771,14 @@ static SBR_ERROR sbrDecoder_DecodeElement(
int copyFrameSize =
codecFrameSize * self->pQmfDomain->QmfDomainOut->fb.no_channels;
copyFrameSize /= self->pQmfDomain->QmfDomainIn->fb.no_channels;
- INT_PCM *ptr;
+ LONG *ptr;
INT i;
FDK_ASSERT(strideOut == 2);
ptr = timeData;
for (i = copyFrameSize >> 1; i--;) {
- INT_PCM tmp; /* This temporal variable is required because some
- compilers can't do *ptr++ = *ptr++ correctly. */
+ LONG tmp; /* This temporal variable is required because some compilers
+ can't do *ptr++ = *ptr++ correctly. */
tmp = *ptr++;
*ptr++ = tmp;
tmp = *ptr++;
@@ -1808,12 +1791,13 @@ static SBR_ERROR sbrDecoder_DecodeElement(
return errorStatus;
}
-SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input,
- INT_PCM *timeData, const int timeDataSize,
- int *numChannels, int *sampleRate,
+SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, LONG *input, LONG *timeData,
+ const int timeDataSize, int *numChannels,
+ int *sampleRate,
const FDK_channelMapDescr *const mapDescr,
const int mapIdx, const int coreDecodedOk,
- UCHAR *psDecoded) {
+ UCHAR *psDecoded, const INT inDataHeadroom,
+ INT *outDataHeadroom) {
SBR_ERROR errorStatus = SBRDEC_OK;
int psPossible;
@@ -1850,6 +1834,9 @@ SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input,
psPossible = 0;
}
+ self->sbrInDataHeadroom = inDataHeadroom;
+ *outDataHeadroom = (INT)(8);
+
/* Make sure that even if no SBR data was found/parsed *psDecoded is returned
* 1 if psPossible was 0. */
if (psPossible == 0) {