diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2024-01-05 17:50:19 +0100 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2024-01-05 17:50:19 +0100 |
commit | 571316f329948dc464cc2be37b210f0b3e7816f7 (patch) | |
tree | 8396262af9d84f5a0490af9805cde11cf5fc9eed /libSBRdec/src | |
parent | e778887e4e5589528b06b04404ce4c71aaae267a (diff) | |
parent | 716f4394641d53f0d79c9ddac3fa93b03a49f278 (diff) | |
download | fdk-aac-571316f329948dc464cc2be37b210f0b3e7816f7.tar.gz fdk-aac-571316f329948dc464cc2be37b210f0b3e7816f7.tar.bz2 fdk-aac-571316f329948dc464cc2be37b210f0b3e7816f7.zip |
Merge fdk-aac 'v2.0.3' into dabplus2dabplus2
Diffstat (limited to 'libSBRdec/src')
-rw-r--r-- | libSBRdec/src/arm/lpp_tran_arm.cpp | 159 | ||||
-rw-r--r-- | libSBRdec/src/env_calc.cpp | 48 | ||||
-rw-r--r-- | libSBRdec/src/hbe.cpp | 51 | ||||
-rw-r--r-- | libSBRdec/src/lpp_tran.cpp | 112 | ||||
-rw-r--r-- | libSBRdec/src/lpp_tran.h | 4 | ||||
-rw-r--r-- | libSBRdec/src/sbr_dec.cpp | 24 | ||||
-rw-r--r-- | libSBRdec/src/sbrdec_drc.cpp | 53 | ||||
-rw-r--r-- | libSBRdec/src/sbrdec_freq_sca.cpp | 16 | ||||
-rw-r--r-- | libSBRdec/src/sbrdecoder.cpp | 16 |
9 files changed, 163 insertions, 320 deletions
diff --git a/libSBRdec/src/arm/lpp_tran_arm.cpp b/libSBRdec/src/arm/lpp_tran_arm.cpp deleted file mode 100644 index db1948f..0000000 --- a/libSBRdec/src/arm/lpp_tran_arm.cpp +++ /dev/null @@ -1,159 +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): Arthur Tritthart - - Description: (ARM optimised) LPP transposer subroutines - -*******************************************************************************/ - -#if defined(__arm__) - -#define FUNCTION_LPPTRANSPOSER_func1 - -#ifdef FUNCTION_LPPTRANSPOSER_func1 - -/* Note: This code requires only 43 cycles per iteration instead of 61 on - * ARM926EJ-S */ -static void lppTransposer_func1(FIXP_DBL *lowBandReal, FIXP_DBL *lowBandImag, - FIXP_DBL **qmfBufferReal, - FIXP_DBL **qmfBufferImag, int loops, int hiBand, - int dynamicScale, int descale, FIXP_SGL a0r, - FIXP_SGL a0i, FIXP_SGL a1r, FIXP_SGL a1i, - const int fPreWhitening, - FIXP_DBL preWhiteningGain, - int preWhiteningGains_sf) { - FIXP_DBL real1, real2, imag1, imag2, accu1, accu2; - - real2 = lowBandReal[-2]; - real1 = lowBandReal[-1]; - imag2 = lowBandImag[-2]; - imag1 = lowBandImag[-1]; - for (int i = 0; i < loops; i++) { - accu1 = fMultDiv2(a0r, real1); - accu2 = fMultDiv2(a0i, imag1); - accu1 = fMultAddDiv2(accu1, a1r, real2); - accu2 = fMultAddDiv2(accu2, a1i, imag2); - real2 = fMultDiv2(a1i, real2); - accu1 = accu1 - accu2; - accu1 = accu1 >> dynamicScale; - - accu2 = fMultAddDiv2(real2, a1r, imag2); - real2 = real1; - imag2 = imag1; - accu2 = fMultAddDiv2(accu2, a0i, real1); - real1 = lowBandReal[i]; - accu2 = fMultAddDiv2(accu2, a0r, imag1); - imag1 = lowBandImag[i]; - accu2 = accu2 >> dynamicScale; - - accu1 <<= 1; - accu2 <<= 1; - accu1 += (real1 >> descale); - accu2 += (imag1 >> descale); - if (fPreWhitening) { - accu1 = scaleValueSaturate(fMultDiv2(accu1, preWhiteningGain), - preWhiteningGains_sf); - accu2 = scaleValueSaturate(fMultDiv2(accu2, preWhiteningGain), - preWhiteningGains_sf); - } - qmfBufferReal[i][hiBand] = accu1; - qmfBufferImag[i][hiBand] = accu2; - } -} -#endif /* #ifdef FUNCTION_LPPTRANSPOSER_func1 */ - -#endif /* __arm__ */ diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index 0b2f651..cefa612 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -664,7 +664,7 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag, gain_sf[i] = mult_sf - total_power_low_sf + sf2; gain[i] = sqrtFixp_lookup(gain[i], &gain_sf[i]); if (gain_sf[i] < 0) { - gain[i] >>= -gain_sf[i]; + gain[i] >>= fMin(DFRACT_BITS - 1, -gain_sf[i]); gain_sf[i] = 0; } } else { @@ -683,11 +683,6 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag, /* gain[i] = g_inter[i] */ for (i = 0; i < nbSubsample; ++i) { - if (gain_sf[i] < 0) { - gain[i] >>= -gain_sf[i]; - gain_sf[i] = 0; - } - /* calculate: gain[i] = 1.0f + gamma * (gain[i] - 1.0f); */ FIXP_DBL one = (FIXP_DBL)MAXVAL_DBL >> gain_sf[i]; /* to substract this from gain[i] */ @@ -755,23 +750,15 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag, int gain_adj_sf = gain_adj_2_sf; for (i = 0; i < nbSubsample; ++i) { - gain[i] = fMult(gain[i], gain_adj); - gain_sf[i] += gain_adj_sf; - - /* limit gain */ - if (gain_sf[i] > INTER_TES_SF_CHANGE) { - gain[i] = (FIXP_DBL)MAXVAL_DBL; - gain_sf[i] = INTER_TES_SF_CHANGE; - } - } - - for (i = 0; i < nbSubsample; ++i) { - /* equalize gain[]'s scale factors */ - gain[i] >>= INTER_TES_SF_CHANGE - gain_sf[i]; + int gain_e = fMax( + fMin(gain_sf[i] + gain_adj_sf - INTER_TES_SF_CHANGE, DFRACT_BITS - 1), + -(DFRACT_BITS - 1)); + FIXP_DBL gain_final = fMult(gain[i], gain_adj); + gain_final = scaleValueSaturate(gain_final, gain_e); for (j = lowSubband; j < highSubband; j++) { - qmfReal[startPos + i][j] = fMult(qmfReal[startPos + i][j], gain[i]); - qmfImag[startPos + i][j] = fMult(qmfImag[startPos + i][j], gain[i]); + qmfReal[startPos + i][j] = fMult(qmfReal[startPos + i][j], gain_final); + qmfImag[startPos + i][j] = fMult(qmfImag[startPos + i][j], gain_final); } } } else { /* gamma_idx == 0 */ @@ -1398,6 +1385,17 @@ void calculateSbrEnvelope( */ noise_e = (start_pos < no_cols) ? adj_e : final_e; + if (start_pos >= no_cols) { + int diff = h_sbr_cal_env->filtBufferNoise_e - noise_e; + if (diff > 0) { + int s = getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands); + if (diff > s) { + final_e += diff - s; + noise_e = final_e; + } + } + } + /* Convert energies to amplitude levels */ @@ -2741,6 +2739,9 @@ static void adjustTimeSlotHQ_GainAndNoise( fMult(direct_ratio, noiseLevel[k]); } + smoothedNoise = fMax(fMin(smoothedNoise, (FIXP_DBL)(MAXVAL_DBL / 2)), + (FIXP_DBL)(MINVAL_DBL / 2)); + /* The next 2 multiplications constitute the actual envelope adjustment of the signal and should be carried out with full accuracy @@ -2930,6 +2931,9 @@ static void adjustTimeSlotHQ( fMult(direct_ratio, noiseLevel[k]); } + smoothedNoise = fMax(fMin(smoothedNoise, (FIXP_DBL)(MAXVAL_DBL / 2)), + (FIXP_DBL)(MINVAL_DBL / 2)); + /* The next 2 multiplications constitute the actual envelope adjustment of the signal and should be carried out with full accuracy diff --git a/libSBRdec/src/hbe.cpp b/libSBRdec/src/hbe.cpp index 77cb8af..9485823 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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1400,42 +1400,27 @@ void QmfTransposerApply(HANDLE_HBE_TRANSPOSER hQmfTransposer, if (shift_ov != 0) { for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) { - for (band = 0; band < QMF_SYNTH_CHANNELS; band++) { - if (shift_ov >= 0) { - hQmfTransposer->qmfHBEBufReal_F[i][band] <<= shift_ov; - hQmfTransposer->qmfHBEBufImag_F[i][band] <<= shift_ov; - } else { - hQmfTransposer->qmfHBEBufReal_F[i][band] >>= (-shift_ov); - hQmfTransposer->qmfHBEBufImag_F[i][band] >>= (-shift_ov); - } - } + scaleValuesSaturate(&hQmfTransposer->qmfHBEBufReal_F[i][0], + QMF_SYNTH_CHANNELS, shift_ov); + scaleValuesSaturate(&hQmfTransposer->qmfHBEBufImag_F[i][0], + QMF_SYNTH_CHANNELS, shift_ov); } - } - if ((keepStatesSyncedMode == KEEP_STATES_SYNCED_OFF) && shift_ov != 0) { - for (i = timeStep * firstSlotOffsset; i < ov_len; i++) { - for (band = hQmfTransposer->startBand; band < hQmfTransposer->stopBand; - band++) { - if (shift_ov >= 0) { - ppQmfBufferOutReal_F[i][band] <<= shift_ov; - ppQmfBufferOutImag_F[i][band] <<= shift_ov; - } else { - ppQmfBufferOutReal_F[i][band] >>= (-shift_ov); - ppQmfBufferOutImag_F[i][band] >>= (-shift_ov); - } + if (keepStatesSyncedMode == KEEP_STATES_SYNCED_OFF) { + int nBands = + fMax(0, hQmfTransposer->stopBand - hQmfTransposer->startBand); + + for (i = timeStep * firstSlotOffsset; i < ov_len; i++) { + scaleValuesSaturate(&ppQmfBufferOutReal_F[i][hQmfTransposer->startBand], + nBands, shift_ov); + scaleValuesSaturate(&ppQmfBufferOutImag_F[i][hQmfTransposer->startBand], + nBands, shift_ov); } - } - /* shift lpc filterstates */ - for (i = 0; i < timeStep * firstSlotOffsset + LPC_ORDER; i++) { - for (band = 0; band < (64); band++) { - if (shift_ov >= 0) { - lpcFilterStatesReal[i][band] <<= shift_ov; - lpcFilterStatesImag[i][band] <<= shift_ov; - } else { - lpcFilterStatesReal[i][band] >>= (-shift_ov); - lpcFilterStatesImag[i][band] >>= (-shift_ov); - } + /* shift lpc filterstates */ + for (i = 0; i < timeStep * firstSlotOffsset + LPC_ORDER; i++) { + scaleValuesSaturate(&lpcFilterStatesReal[i][0], (64), shift_ov); + scaleValuesSaturate(&lpcFilterStatesImag[i][0], (64), shift_ov); } } } diff --git a/libSBRdec/src/lpp_tran.cpp b/libSBRdec/src/lpp_tran.cpp index 93e1158..68a25bf 100644 --- a/libSBRdec/src/lpp_tran.cpp +++ b/libSBRdec/src/lpp_tran.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -132,10 +132,6 @@ amm-info@iis.fraunhofer.de #include "HFgen_preFlat.h" -#if defined(__arm__) -#include "arm/lpp_tran_arm.cpp" -#endif - #define LPC_SCALE_FACTOR 2 /*! @@ -220,19 +216,21 @@ static inline void calc_qmfBufferReal(FIXP_DBL **qmfBufferReal, const FIXP_DBL *const lowBandReal, const int startSample, const int stopSample, const UCHAR hiBand, - const int dynamicScale, const int descale, + const int dynamicScale, const FIXP_SGL a0r, const FIXP_SGL a1r) { - FIXP_DBL accu1, accu2; - int i; + const int dynscale = fixMax(0, dynamicScale - 1) + 1; + const int rescale = -fixMin(0, dynamicScale - 1) + 1; + const int descale = + fixMin(DFRACT_BITS - 1, LPC_SCALE_FACTOR + dynamicScale + rescale); + + for (int i = 0; i < stopSample - startSample; i++) { + FIXP_DBL accu; - for (i = 0; i < stopSample - startSample; i++) { - accu1 = fMultDiv2(a1r, lowBandReal[i]); - accu1 = (fMultDiv2(a0r, lowBandReal[i + 1]) + accu1); - accu1 = accu1 >> dynamicScale; + accu = fMultDiv2(a1r, lowBandReal[i]) + fMultDiv2(a0r, lowBandReal[i + 1]); + accu = (lowBandReal[i + 2] >> descale) + (accu >> dynscale); - accu1 <<= 1; - accu2 = (lowBandReal[i + 2] >> descale); - qmfBufferReal[i + startSample][hiBand] = accu1 + accu2; + qmfBufferReal[i + startSample][hiBand] = + SATURATE_LEFT_SHIFT(accu, rescale, DFRACT_BITS); } } @@ -529,7 +527,7 @@ void lppTransposer( if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) { resetLPCCoeffs = 1; } else { - alphar[1] = FX_DBL2FX_SGL(scaleValue(result, scale)); + alphar[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale)); if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { alphar[1] = -alphar[1]; } @@ -557,7 +555,7 @@ void lppTransposer( scale)) { resetLPCCoeffs = 1; } else { - alphai[1] = FX_DBL2FX_SGL(scaleValue(result, scale)); + alphai[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale)); if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { alphai[1] = -alphai[1]; } @@ -596,7 +594,7 @@ void lppTransposer( } else { INT scale; FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); - alphar[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1)); + alphar[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1)); if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) alphar[0] = -alphar[0]; @@ -616,7 +614,7 @@ void lppTransposer( } else { INT scale; FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); - alphai[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1)); + alphai[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1)); if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) alphai[0] = -alphai[0]; } @@ -659,7 +657,7 @@ void lppTransposer( INT scale; FIXP_DBL result = fDivNorm(fixp_abs(ac.r01r), fixp_abs(ac.r11r), &scale); - k1 = scaleValue(result, scale); + k1 = scaleValueSaturate(result, scale); if (!((ac.r01r < FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))) { k1 = -k1; @@ -771,52 +769,50 @@ void lppTransposer( } else { /* bw <= 0 */ if (!useLP) { - int descale = - fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)); -#ifdef FUNCTION_LPPTRANSPOSER_func1 - lppTransposer_func1( - lowBandReal + LPC_ORDER + startSample, - lowBandImag + LPC_ORDER + startSample, - qmfBufferReal + startSample, qmfBufferImag + startSample, - stopSample - startSample, (int)hiBand, dynamicScale, descale, a0r, - a0i, a1r, a1i, fPreWhitening, preWhiteningGains[loBand], - preWhiteningGains_exp[loBand] + 1); -#else + const int dynscale = fixMax(0, dynamicScale - 2) + 1; + const int rescale = -fixMin(0, dynamicScale - 2) + 1; + const int descale = fixMin(DFRACT_BITS - 1, + LPC_SCALE_FACTOR + dynamicScale + rescale); + for (i = startSample; i < stopSample; i++) { FIXP_DBL accu1, accu2; - accu1 = (fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) - - fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1]) + - fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) - - fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >> - dynamicScale; - accu2 = (fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) + - fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1]) + - fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) + - fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >> - dynamicScale; - - accu1 = (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << 1); - accu2 = (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << 1); + accu1 = ((fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) - + fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1])) >> + 1) + + ((fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) - + fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >> + 1); + accu2 = ((fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) + + fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1])) >> + 1) + + ((fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) + + fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >> + 1); + + accu1 = + (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 >> dynscale); + accu2 = + (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 >> dynscale); if (fPreWhitening) { - accu1 = scaleValueSaturate( + qmfBufferReal[i][hiBand] = scaleValueSaturate( fMultDiv2(accu1, preWhiteningGains[loBand]), - preWhiteningGains_exp[loBand] + 1); - accu2 = scaleValueSaturate( + preWhiteningGains_exp[loBand] + 1 + rescale); + qmfBufferImag[i][hiBand] = scaleValueSaturate( fMultDiv2(accu2, preWhiteningGains[loBand]), - preWhiteningGains_exp[loBand] + 1); + preWhiteningGains_exp[loBand] + 1 + rescale); + } else { + qmfBufferReal[i][hiBand] = + SATURATE_LEFT_SHIFT(accu1, rescale, DFRACT_BITS); + qmfBufferImag[i][hiBand] = + SATURATE_LEFT_SHIFT(accu2, rescale, DFRACT_BITS); } - qmfBufferReal[i][hiBand] = accu1; - qmfBufferImag[i][hiBand] = accu2; } -#endif } else { FDK_ASSERT(dynamicScale >= 0); calc_qmfBufferReal( qmfBufferReal, &(lowBandReal[LPC_ORDER + startSample - 2]), - startSample, stopSample, hiBand, dynamicScale, - fMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)), a0r, - a1r); + startSample, stopSample, hiBand, dynamicScale, a0r, a1r); } } /* bw <= 0 */ @@ -1066,7 +1062,7 @@ void lppTransposerHBE( if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) { resetLPCCoeffs = 1; } else { - alphar[1] = FX_DBL2FX_SGL(scaleValue(result, scale)); + alphar[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale)); if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { alphar[1] = -alphar[1]; } @@ -1092,7 +1088,7 @@ void lppTransposerHBE( (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >> scale)) { resetLPCCoeffs = 1; } else { - alphai[1] = FX_DBL2FX_SGL(scaleValue(result, scale)); + alphai[1] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale)); if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { alphai[1] = -alphai[1]; } @@ -1121,7 +1117,7 @@ void lppTransposerHBE( } else { INT scale; FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); - alphar[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1)); + alphar[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1)); if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) alphar[0] = -alphar[0]; @@ -1140,7 +1136,7 @@ void lppTransposerHBE( } else { INT scale; FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); - alphai[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1)); + alphai[0] = FX_DBL2FX_SGL(scaleValueSaturate(result, scale + 1)); if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) { alphai[0] = -alphai[0]; } diff --git a/libSBRdec/src/lpp_tran.h b/libSBRdec/src/lpp_tran.h index 51b4395..21c4101 100644 --- a/libSBRdec/src/lpp_tran.h +++ b/libSBRdec/src/lpp_tran.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 - 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -207,7 +207,7 @@ typedef struct { inverse filtering levels */ PATCH_PARAM - patchParam[MAX_NUM_PATCHES]; /*!< new parameter set for patching */ + patchParam[MAX_NUM_PATCHES + 1]; /*!< new parameter set for patching */ WHITENING_FACTORS whFactors; /*!< the pole moving factors for certain whitening levels as indicated in the bitstream diff --git a/libSBRdec/src/sbr_dec.cpp b/libSBRdec/src/sbr_dec.cpp index b1fb0da..919e9bb 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 - 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 @@ -713,7 +713,8 @@ void sbr_dec( } else { /* (flags & SBRDEC_PS_DECODED) */ INT sdiff; - INT scaleFactorHighBand, scaleFactorLowBand_ov, scaleFactorLowBand_no_ov; + INT scaleFactorHighBand, scaleFactorLowBand_ov, scaleFactorLowBand_no_ov, + outScalefactor, outScalefactorR, outScalefactorL; HANDLE_QMF_FILTER_BANK synQmf = &hSbrDec->qmfDomainOutCh->fb; HANDLE_QMF_FILTER_BANK synQmfRight = &hSbrDecRight->qmfDomainOutCh->fb; @@ -744,7 +745,7 @@ void sbr_dec( */ FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <= QMF_MAX_SYNTHESIS_BANDS); - qmfChangeOutScalefactor(synQmfRight, -(8)); + synQmfRight->outScalefactor = synQmf->outScalefactor; FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates, 9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis * sizeof(FIXP_QSS)); @@ -788,9 +789,11 @@ void sbr_dec( FDKmemcpy(&hSbrDecRight->sbrDrcChannel, &hSbrDec->sbrDrcChannel, sizeof(SBRDEC_DRC_CHANNEL)); - for (i = 0; i < synQmf->no_col; i++) { /* ----- no_col loop ----- */ + outScalefactor = maxShift - (8); + outScalefactorL = outScalefactorR = + sbrInDataHeadroom + 1; /* +1: psDiffScale! (MPEG-PS) */ - INT outScalefactorR, outScalefactorL; + for (i = 0; i < synQmf->no_col; i++) { /* ----- no_col loop ----- */ /* qmf timeslot of right channel */ FIXP_DBL *rQmfReal = pWorkBuffer; @@ -815,27 +818,20 @@ void sbr_dec( ? scaleFactorLowBand_ov : scaleFactorLowBand_no_ov, scaleFactorHighBand, synQmf->lsb, synQmf->usb); - - outScalefactorL = outScalefactorR = - 1 + sbrInDataHeadroom; /* psDiffScale! (MPEG-PS) */ } sbrDecoder_drcApplySlot(/* right channel */ &hSbrDecRight->sbrDrcChannel, rQmfReal, rQmfImag, i, synQmfRight->no_col, maxShift); - outScalefactorR += maxShift; - sbrDecoder_drcApplySlot(/* left channel */ &hSbrDec->sbrDrcChannel, *(pLowBandReal + i), *(pLowBandImag + i), i, synQmf->no_col, maxShift); - outScalefactorL += maxShift; - if (!(flags & SBRDEC_SKIP_QMF_SYN)) { - qmfChangeOutScalefactor(synQmf, -(8)); - qmfChangeOutScalefactor(synQmfRight, -(8)); + qmfChangeOutScalefactor(synQmf, outScalefactor); + qmfChangeOutScalefactor(synQmfRight, outScalefactor); qmfSynthesisFilteringSlot( synQmfRight, rQmfReal, /* QMF real buffer */ diff --git a/libSBRdec/src/sbrdec_drc.cpp b/libSBRdec/src/sbrdec_drc.cpp index 2d73f32..089d046 100644 --- a/libSBRdec/src/sbrdec_drc.cpp +++ b/libSBRdec/src/sbrdec_drc.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 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -233,14 +233,19 @@ void sbrDecoder_drcApplySlot(HANDLE_SBR_DRC_CHANNEL hDrcData, if (hDrcData->winSequenceCurr != 2) { /* long window */ int j = col + (numQmfSubSamples >> 1); - if (hDrcData->drcInterpolationSchemeCurr == 0) { - INT k = (frameLenFlag) ? 0x4444445 : 0x4000000; + if (j < winBorderToColMap[15]) { + if (hDrcData->drcInterpolationSchemeCurr == 0) { + INT k = (frameLenFlag) ? 0x4444445 : 0x4000000; - alphaValue = (FIXP_DBL)(j * k); - } else { - if (j >= (int)winBorderToColMap[hDrcData->drcInterpolationSchemeCurr]) { - alphaValue = (FIXP_DBL)MAXVAL_DBL; + alphaValue = (FIXP_DBL)(j * k); + } else { + if (j >= + (int)winBorderToColMap[hDrcData->drcInterpolationSchemeCurr]) { + alphaValue = (FIXP_DBL)MAXVAL_DBL; + } } + } else { + alphaValue = (FIXP_DBL)MAXVAL_DBL; } } else { /* short windows */ shortDrc = 1; @@ -254,14 +259,19 @@ void sbrDecoder_drcApplySlot(HANDLE_SBR_DRC_CHANNEL hDrcData, if (hDrcData->winSequenceNext != 2) { /* next: long window */ int j = col - (numQmfSubSamples >> 1); - if (hDrcData->drcInterpolationSchemeNext == 0) { - INT k = (frameLenFlag) ? 0x4444445 : 0x4000000; + if (j < winBorderToColMap[15]) { + if (hDrcData->drcInterpolationSchemeNext == 0) { + INT k = (frameLenFlag) ? 0x4444445 : 0x4000000; - alphaValue = (FIXP_DBL)(j * k); - } else { - if (j >= (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) { - alphaValue = (FIXP_DBL)MAXVAL_DBL; + alphaValue = (FIXP_DBL)(j * k); + } else { + if (j >= + (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) { + alphaValue = (FIXP_DBL)MAXVAL_DBL; + } } + } else { + alphaValue = (FIXP_DBL)MAXVAL_DBL; } fact_mag = hDrcData->nextFact_mag; @@ -289,14 +299,19 @@ void sbrDecoder_drcApplySlot(HANDLE_SBR_DRC_CHANNEL hDrcData, if (hDrcData->winSequenceNext != 2) { /* long window */ int j = col - (numQmfSubSamples >> 1); - if (hDrcData->drcInterpolationSchemeNext == 0) { - INT k = (frameLenFlag) ? 0x4444445 : 0x4000000; + if (j < winBorderToColMap[15]) { + if (hDrcData->drcInterpolationSchemeNext == 0) { + INT k = (frameLenFlag) ? 0x4444445 : 0x4000000; - alphaValue = (FIXP_DBL)(j * k); - } else { - if (j >= (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) { - alphaValue = (FIXP_DBL)MAXVAL_DBL; + alphaValue = (FIXP_DBL)(j * k); + } else { + if (j >= + (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) { + alphaValue = (FIXP_DBL)MAXVAL_DBL; + } } + } else { + alphaValue = (FIXP_DBL)MAXVAL_DBL; } } else { /* short windows */ shortDrc = 1; diff --git a/libSBRdec/src/sbrdec_freq_sca.cpp b/libSBRdec/src/sbrdec_freq_sca.cpp index e187656..daa3554 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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -765,9 +765,6 @@ resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags) { sbrdecUpdateLoRes(hFreq->freqBandTable[0], &nBandsLo, hFreq->freqBandTable[1], nBandsHi); - hFreq->nSfb[0] = nBandsLo; - hFreq->nSfb[1] = nBandsHi; - /* Check index to freqBandTable[0] */ if (!(nBandsLo > 0) || (nBandsLo > (((hHeaderData->numberOfAnalysisBands == 16) @@ -777,6 +774,9 @@ resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags) { return SBRDEC_UNSUPPORTED_CONFIG; } + hFreq->nSfb[0] = nBandsLo; + hFreq->nSfb[1] = nBandsHi; + lsb = hFreq->freqBandTable[0][0]; usb = hFreq->freqBandTable[0][nBandsLo]; @@ -814,15 +814,15 @@ resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags) { if (intTemp == 0) intTemp = 1; + if (intTemp > MAX_NOISE_COEFFS) { + return SBRDEC_UNSUPPORTED_CONFIG; + } + hFreq->nNfb = intTemp; } hFreq->nInvfBands = hFreq->nNfb; - if (hFreq->nNfb > MAX_NOISE_COEFFS) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - /* Get noise bands */ sbrdecDownSampleLoRes(hFreq->freqBandTableNoise, hFreq->nNfb, hFreq->freqBandTable[0], nBandsLo); diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index b101a4a..7718695 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 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -961,8 +961,10 @@ SBR_ERROR sbrDecoder_SetParam(HANDLE_SBRDECODER self, const SBRDEC_PARAM param, /* Set sync state UPSAMPLING for the corresponding slot. This switches off bitstream parsing until a new header arrives. */ - hSbrHeader->syncState = UPSAMPLING; - hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE; + if (hSbrHeader->syncState != SBR_NOT_INITIALIZED) { + hSbrHeader->syncState = UPSAMPLING; + hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE; + } } } } break; @@ -1371,7 +1373,9 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, } if (headerStatus == HEADER_ERROR) { /* Corrupt SBR info data, do not decode and switch to UPSAMPLING */ - hSbrHeader->syncState = UPSAMPLING; + hSbrHeader->syncState = hSbrHeader->syncState > UPSAMPLING + ? UPSAMPLING + : hSbrHeader->syncState; fDoDecodeSbrData = 0; sbrHeaderPresent = 0; } @@ -1610,7 +1614,9 @@ static SBR_ERROR sbrDecoder_DecodeElement( /* No valid SBR payload available, hence switch to upsampling (in all * headers) */ for (hdrIdx = 0; hdrIdx < ((1) + 1); hdrIdx += 1) { - self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING; + if (self->sbrHeader[elementIndex][hdrIdx].syncState > UPSAMPLING) { + self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING; + } } } else { /* Move frame pointer to the next slot which is up to be decoded/applied |