diff options
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  | 
