aboutsummaryrefslogtreecommitdiffstats
path: root/libSBRenc/src/tran_det.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libSBRenc/src/tran_det.cpp')
-rw-r--r--libSBRenc/src/tran_det.cpp1103
1 files changed, 558 insertions, 545 deletions
diff --git a/libSBRenc/src/tran_det.cpp b/libSBRenc/src/tran_det.cpp
index 33ea60e..ba9ae68 100644
--- a/libSBRenc/src/tran_det.cpp
+++ b/libSBRenc/src/tran_det.cpp
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© 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.
+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:
+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 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
+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.
+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.
+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."
+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.
+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.
+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.
+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
@@ -79,19 +90,28 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
+
+ Author(s): Tobias Chalupka
+
+ Description: SBR encoder transient detector
+
+*******************************************************************************/
#include "tran_det.h"
#include "fram_gen.h"
-#include "sbr_ram.h"
+#include "sbrenc_ram.h"
#include "sbr_misc.h"
#include "genericStds.h"
#define NORM_QMF_ENERGY 9.31322574615479E-10 /* 2^-30 */
-/* static FIXP_DBL ABS_THRES = fixMax( FL2FXCONST_DBL(1.28e5 * NORM_QMF_ENERGY), (FIXP_DBL)1) Minimum threshold for detecting changes */
+/* static FIXP_DBL ABS_THRES = fixMax( FL2FXCONST_DBL(1.28e5 *
+ * NORM_QMF_ENERGY), (FIXP_DBL)1) Minimum threshold for detecting changes */
#define ABS_THRES ((FIXP_DBL)16)
/*******************************************************************************
@@ -106,126 +126,128 @@ amm-info@iis.fraunhofer.de
\return calculated value
*******************************************************************************/
-#define NRG_SHIFT 3 /* for energy summation */
-
-static FIXP_DBL spectralChange(FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS],
- INT *scaleEnergies,
- FIXP_DBL EnergyTotal,
- INT nSfb,
- INT start,
- INT border,
- INT YBufferWriteOffset,
- INT stop,
- INT *result_e)
-{
- INT i,j;
- INT len1,len2;
- SCHAR energies_e_diff[NUMBER_TIME_SLOTS_2304], energies_e, energyTotal_e=19, energies_e_add;
+#define NRG_SHIFT 3 /* for energy summation */
+
+static FIXP_DBL spectralChange(
+ FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS],
+ INT *scaleEnergies, FIXP_DBL EnergyTotal, INT nSfb, INT start, INT border,
+ INT YBufferWriteOffset, INT stop, INT *result_e) {
+ INT i, j;
+ INT len1, len2;
+ SCHAR energies_e_diff[NUMBER_TIME_SLOTS_2304], energies_e, energyTotal_e = 19,
+ energies_e_add;
SCHAR prevEnergies_e_diff, newEnergies_e_diff;
- FIXP_DBL tmp0,tmp1;
- FIXP_DBL accu1,accu2,accu1_init,accu2_init;
+ FIXP_DBL tmp0, tmp1;
FIXP_DBL delta, delta_sum;
INT accu_e, tmp_e;
delta_sum = FL2FXCONST_DBL(0.0f);
*result_e = 0;
- len1 = border-start;
- len2 = stop-border;
+ len1 = border - start;
+ len2 = stop - border;
/* prefer borders near the middle of the frame */
- FIXP_DBL pos_weight;
- pos_weight = FL2FXCONST_DBL(0.5f) - (len1*GetInvInt(len1+len2));
- pos_weight = /*FL2FXCONST_DBL(1.0)*/ (FIXP_DBL)MAXVAL_DBL - (fMult(pos_weight, pos_weight)<<2);
+ FIXP_DBL pos_weight;
+ pos_weight = FL2FXCONST_DBL(0.5f) - (len1 * GetInvInt(len1 + len2));
+ pos_weight = /*FL2FXCONST_DBL(1.0)*/ (FIXP_DBL)MAXVAL_DBL -
+ (fMult(pos_weight, pos_weight) << 2);
/*** Calc scaling for energies ***/
FDK_ASSERT(scaleEnergies[0] >= 0);
FDK_ASSERT(scaleEnergies[1] >= 0);
- energies_e = 19 - FDKmin(scaleEnergies[0], scaleEnergies[1]);
+ energies_e = 19 - fMin(scaleEnergies[0], scaleEnergies[1]);
/* limit shift for energy accumulation, energies_e can be -10 min. */
if (energies_e < -10) {
- energies_e_add = -10 - energies_e;
- energies_e = -10;
+ energies_e_add = -10 - energies_e;
+ energies_e = -10;
} else if (energies_e > 17) {
- energies_e_add = energies_e - 17;
- energies_e = 17;
+ energies_e_add = energies_e - 17;
+ energies_e = 17;
} else {
- energies_e_add = 0;
+ energies_e_add = 0;
}
- /* compensate scaling differences between scaleEnergies[0] and scaleEnergies[1] */
- prevEnergies_e_diff = scaleEnergies[0] - FDKmin(scaleEnergies[0], scaleEnergies[1]) + energies_e_add + NRG_SHIFT;
- newEnergies_e_diff = scaleEnergies[1] - FDKmin(scaleEnergies[0], scaleEnergies[1]) + energies_e_add + NRG_SHIFT;
+ /* compensate scaling differences between scaleEnergies[0] and
+ * scaleEnergies[1] */
+ prevEnergies_e_diff = scaleEnergies[0] -
+ fMin(scaleEnergies[0], scaleEnergies[1]) +
+ energies_e_add + NRG_SHIFT;
+ newEnergies_e_diff = scaleEnergies[1] -
+ fMin(scaleEnergies[0], scaleEnergies[1]) +
+ energies_e_add + NRG_SHIFT;
- prevEnergies_e_diff = fMin(prevEnergies_e_diff, DFRACT_BITS-1);
- newEnergies_e_diff = fMin(newEnergies_e_diff, DFRACT_BITS-1);
+ prevEnergies_e_diff = fMin(prevEnergies_e_diff, DFRACT_BITS - 1);
+ newEnergies_e_diff = fMin(newEnergies_e_diff, DFRACT_BITS - 1);
- for (i=start; i<YBufferWriteOffset; i++) {
+ for (i = start; i < YBufferWriteOffset; i++) {
energies_e_diff[i] = prevEnergies_e_diff;
}
- for (i=YBufferWriteOffset; i<stop; i++) {
+ for (i = YBufferWriteOffset; i < stop; i++) {
energies_e_diff[i] = newEnergies_e_diff;
}
/* Sum up energies of all QMF-timeslots for both halfs */
- FDK_ASSERT(len1<=8); /* otherwise an overflow is possible */
- FDK_ASSERT(len2<=8); /* otherwise an overflow is possible */
- /* init with some energy to prevent division by zero
- and to prevent splitting for very low levels */
- accu1_init = scaleValue((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY))),-energies_e);
- accu2_init = scaleValue((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY))),-energies_e);
- accu1_init = fMult(accu1_init, (FIXP_DBL)len1<<((DFRACT_BITS-1)-NRG_SHIFT-1))<<1;
- accu2_init = fMult(accu2_init, (FIXP_DBL)len2<<((DFRACT_BITS-1)-NRG_SHIFT-1))<<1;
+ FDK_ASSERT(len1 <= 8); /* otherwise an overflow is possible */
+ FDK_ASSERT(len2 <= 8); /* otherwise an overflow is possible */
- for (j=0; j<nSfb; j++) {
-
- accu1 = accu1_init;
- accu2 = accu2_init;
- accu_e = energies_e+3;
+ for (j = 0; j < nSfb; j++) {
+ FIXP_DBL accu1 = FL2FXCONST_DBL(0.f);
+ FIXP_DBL accu2 = FL2FXCONST_DBL(0.f);
+ accu_e = energies_e + 3;
/* Sum up energies in first half */
- for (i=start; i<border; i++) {
+ for (i = start; i < border; i++) {
accu1 += scaleValue(Energies[i][j], -energies_e_diff[i]);
}
/* Sum up energies in second half */
- for (i=border; i<stop; i++) {
+ for (i = border; i < stop; i++) {
accu2 += scaleValue(Energies[i][j], -energies_e_diff[i]);
}
- /* Energy change in current band */
- #define LN2 FL2FXCONST_DBL(0.6931471806f) /* ln(2) */
+ /* Ensure certain energy to prevent division by zero and to prevent
+ * splitting for very low levels */
+ accu1 = fMax(accu1, (FIXP_DBL)len1);
+ accu2 = fMax(accu2, (FIXP_DBL)len2);
+
+/* Energy change in current band */
+#define LN2 FL2FXCONST_DBL(0.6931471806f) /* ln(2) */
tmp0 = fLog2(accu2, accu_e) - fLog2(accu1, accu_e);
tmp1 = fLog2((FIXP_DBL)len1, 31) - fLog2((FIXP_DBL)len2, 31);
delta = fMult(LN2, (tmp0 + tmp1));
- delta = (FIXP_DBL)FDKabs( delta );
+ delta = (FIXP_DBL)fAbs(delta);
/* Weighting with amplitude ratio of this band */
- accu_e++;
- accu1>>=1;
- accu2>>=1;
+ accu_e++; /* scale at least one bit due to (accu1+accu2) */
+ accu1 >>= 1;
+ accu2 >>= 1;
+
if (accu_e & 1) {
- accu_e++;
- accu1>>=1;
- accu2>>=1;
+ accu_e++; /* for a defined square result exponent, the exponent has to be
+ even */
+ accu1 >>= 1;
+ accu2 >>= 1;
}
- delta_sum += fMult(sqrtFixp(accu1+accu2), delta);
- *result_e = ((accu_e>>1) + LD_DATA_SHIFT);
+ delta_sum += fMult(sqrtFixp(accu1 + accu2), delta);
+ *result_e = ((accu_e >> 1) + LD_DATA_SHIFT);
+ }
+
+ if (energyTotal_e & 1) {
+ energyTotal_e += 1; /* for a defined square result exponent, the exponent
+ has to be even */
+ EnergyTotal >>= 1;
}
- energyTotal_e+=1; /* for a defined square result exponent, the exponent has to be even */
- EnergyTotal<<=1;
delta_sum = fMult(delta_sum, invSqrtNorm2(EnergyTotal, &tmp_e));
- *result_e = *result_e + (tmp_e-(energyTotal_e>>1));
+ *result_e = *result_e + (tmp_e - (energyTotal_e >> 1));
return fMult(delta_sum, pos_weight);
-
}
-
/*******************************************************************************
Functionname: addLowbandEnergies
*******************************************************************************
@@ -238,40 +260,37 @@ static FIXP_DBL spectralChange(FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FRE
\return total energy in the lowband, scaled by the factor 2^19
*******************************************************************************/
-static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
- int *scaleEnergies,
- int YBufferWriteOffset,
- int nrgSzShift,
- int tran_off,
- UCHAR *freqBandTable,
- int slots)
-{
- FIXP_DBL nrgTotal;
+static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies, int *scaleEnergies,
+ int YBufferWriteOffset, int nrgSzShift,
+ int tran_off, UCHAR *freqBandTable,
+ int slots) {
+ INT nrgTotal_e;
+ FIXP_DBL nrgTotal_m;
FIXP_DBL accu1 = FL2FXCONST_DBL(0.0f);
FIXP_DBL accu2 = FL2FXCONST_DBL(0.0f);
- int tran_offdiv2 = tran_off>>nrgSzShift;
- int ts,k;
+ int tran_offdiv2 = tran_off >> nrgSzShift;
+ int ts, k;
/* Sum up lowband energy from one frame at offset tran_off */
/* freqBandTable[LORES] has MAX_FREQ_COEFFS/2 +1 coeefs max. */
- for (ts=tran_offdiv2; ts<YBufferWriteOffset; ts++) {
+ for (ts = tran_offdiv2; ts < YBufferWriteOffset; ts++) {
for (k = 0; k < freqBandTable[0]; k++) {
accu1 += Energies[ts][k] >> 6;
}
}
- for (; ts<tran_offdiv2+(slots>>nrgSzShift); ts++) {
+ for (; ts < tran_offdiv2 + (slots >> nrgSzShift); ts++) {
for (k = 0; k < freqBandTable[0]; k++) {
accu2 += Energies[ts][k] >> 9;
}
}
- nrgTotal = ( scaleValueSaturate(accu1, 1-scaleEnergies[0]) )
- + ( scaleValueSaturate(accu2, 4-scaleEnergies[1]) );
+ nrgTotal_m = fAddNorm(accu1, 1 - scaleEnergies[0], accu2,
+ 4 - scaleEnergies[1], &nrgTotal_e);
+ nrgTotal_m = scaleValueSaturate(nrgTotal_m, nrgTotal_e);
- return(nrgTotal);
+ return (nrgTotal_m);
}
-
/*******************************************************************************
Functionname: addHighbandEnergies
*******************************************************************************
@@ -289,35 +308,35 @@ static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
\return total energy in the highband, scaled by factor 2^19
*******************************************************************************/
-static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */
- INT *scaleEnergies,
- INT YBufferWriteOffset,
- FIXP_DBL EnergiesM[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS], /*!< Combined output */
- UCHAR *RESTRICT freqBandTable,
- INT nSfb,
- INT sbrSlots,
- INT timeStep)
-{
- INT i,j,k,slotIn,slotOut,scale[2];
- INT li,ui;
+static FIXP_DBL addHighbandEnergies(
+ FIXP_DBL **RESTRICT Energies, /*!< input */
+ INT *scaleEnergies, INT YBufferWriteOffset,
+ FIXP_DBL EnergiesM[NUMBER_TIME_SLOTS_2304]
+ [MAX_FREQ_COEFFS], /*!< Combined output */
+ UCHAR *RESTRICT freqBandTable, INT nSfb, INT sbrSlots, INT timeStep) {
+ INT i, j, k, slotIn, slotOut, scale[2];
+ INT li, ui;
FIXP_DBL nrgTotal;
FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
/* Combine QMF-timeslots to SBR-timeslots,
combine QMF-bands to SBR-bands,
combine Left and Right channel */
- for (slotOut=0; slotOut<sbrSlots; slotOut++) {
- slotIn = timeStep*slotOut;
+ for (slotOut = 0; slotOut < sbrSlots; slotOut++) {
+ /* Note: Below slotIn = slotOut and not slotIn = timeStep*slotOut
+ because the Energies[] time resolution is always the SBR slot resolution
+ regardless of the timeStep. */
+ slotIn = slotOut;
- for (j=0; j<nSfb; j++) {
+ for (j = 0; j < nSfb; j++) {
accu = FL2FXCONST_DBL(0.0f);
li = freqBandTable[j];
ui = freqBandTable[j + 1];
- for (k=li; k<ui; k++) {
- for (i=0; i<timeStep; i++) {
- accu += (Energies[(slotIn+i)>>1][k] >> 5);
+ for (k = li; k < ui; k++) {
+ for (i = 0; i < timeStep; i++) {
+ accu += Energies[slotIn][k] >> 5;
}
}
EnergiesM[slotOut][j] = accu;
@@ -325,34 +344,34 @@ static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */
}
/* scale energies down before add up */
- scale[0] = fixMin(8,scaleEnergies[0]);
- scale[1] = fixMin(8,scaleEnergies[1]);
+ scale[0] = fixMin(8, scaleEnergies[0]);
+ scale[1] = fixMin(8, scaleEnergies[1]);
- if ((scaleEnergies[0]-scale[0]) > (DFRACT_BITS-1) || (scaleEnergies[1]-scale[0]) > (DFRACT_BITS-1))
+ if ((scaleEnergies[0] - scale[0]) > (DFRACT_BITS - 1) ||
+ (scaleEnergies[1] - scale[1]) > (DFRACT_BITS - 1))
nrgTotal = FL2FXCONST_DBL(0.0f);
else {
/* Now add all energies */
accu = FL2FXCONST_DBL(0.0f);
- for (slotOut=0; slotOut<YBufferWriteOffset; slotOut++) {
- for (j=0; j<nSfb; j++) {
+ for (slotOut = 0; slotOut < YBufferWriteOffset; slotOut++) {
+ for (j = 0; j < nSfb; j++) {
accu += (EnergiesM[slotOut][j] >> scale[0]);
}
}
- nrgTotal = accu >> (scaleEnergies[0]-scale[0]);
+ nrgTotal = accu >> (scaleEnergies[0] - scale[0]);
- for (slotOut=YBufferWriteOffset; slotOut<sbrSlots; slotOut++) {
- for (j=0; j<nSfb; j++) {
+ for (slotOut = YBufferWriteOffset; slotOut < sbrSlots; slotOut++) {
+ for (j = 0; j < nSfb; j++) {
accu += (EnergiesM[slotOut][j] >> scale[0]);
}
}
- nrgTotal = accu >> (scaleEnergies[1]-scale[1]);
+ nrgTotal = accu >> (scaleEnergies[1] - scale[1]);
}
- return(nrgTotal);
+ return (nrgTotal);
}
-
/*******************************************************************************
Functionname: FDKsbrEnc_frameSplitter
*******************************************************************************
@@ -361,73 +380,55 @@ static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */
If no transient has been detected before, the frame can still be splitted
into 2 envelopes.
*******************************************************************************/
-void
-FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
- INT *scaleEnergies,
- HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
- UCHAR *freqBandTable,
- UCHAR *tran_vector,
- int YBufferWriteOffset,
- int YBufferSzShift,
- int nSfb,
- int timeStep,
- int no_cols,
- FIXP_DBL* tonality)
-{
- if (tran_vector[1]==0) /* no transient was detected */
+void FDKsbrEnc_frameSplitter(
+ FIXP_DBL **Energies, INT *scaleEnergies,
+ HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, UCHAR *freqBandTable,
+ UCHAR *tran_vector, int YBufferWriteOffset, int YBufferSzShift, int nSfb,
+ int timeStep, int no_cols, FIXP_DBL *tonality) {
+ if (tran_vector[1] == 0) /* no transient was detected */
{
FIXP_DBL delta;
INT delta_e;
- FIXP_DBL (*EnergiesM)[MAX_FREQ_COEFFS];
- FIXP_DBL EnergyTotal,newLowbandEnergy,newHighbandEnergy;
+ FIXP_DBL(*EnergiesM)[MAX_FREQ_COEFFS];
+ FIXP_DBL EnergyTotal, newLowbandEnergy, newHighbandEnergy;
INT border;
- INT sbrSlots = fMultI(GetInvInt(timeStep),no_cols);
- C_ALLOC_SCRATCH_START(_EnergiesM, FIXP_DBL, NUMBER_TIME_SLOTS_2304*MAX_FREQ_COEFFS)
+ INT sbrSlots = fMultI(GetInvInt(timeStep), no_cols);
+ C_ALLOC_SCRATCH_START(_EnergiesM, FIXP_DBL,
+ NUMBER_TIME_SLOTS_2304 * MAX_FREQ_COEFFS)
- FDK_ASSERT( sbrSlots * timeStep == no_cols );
+ FDK_ASSERT(sbrSlots * timeStep == no_cols);
EnergiesM = (FIXP_DBL(*)[MAX_FREQ_COEFFS])_EnergiesM;
/*
- Get Lowband-energy over a range of 2 frames (Look half a frame back and ahead).
+ Get Lowband-energy over a range of 2 frames (Look half a frame back and
+ ahead).
*/
- newLowbandEnergy = addLowbandEnergies(Energies,
- scaleEnergies,
- YBufferWriteOffset,
- YBufferSzShift,
- h_sbrTransientDetector->tran_off,
- freqBandTable,
- no_cols);
-
- newHighbandEnergy = addHighbandEnergies(Energies,
- scaleEnergies,
- YBufferWriteOffset,
- EnergiesM,
- freqBandTable,
- nSfb,
- sbrSlots,
- timeStep);
+ newLowbandEnergy = addLowbandEnergies(
+ Energies, scaleEnergies, YBufferWriteOffset, YBufferSzShift,
+ h_sbrTransientDetector->tran_off, freqBandTable, no_cols);
+
+ newHighbandEnergy =
+ addHighbandEnergies(Energies, scaleEnergies, YBufferWriteOffset,
+ EnergiesM, freqBandTable, nSfb, sbrSlots, timeStep);
{
- /* prevLowBandEnergy: Corresponds to 1 frame, starting with half a frame look-behind
- newLowbandEnergy: Corresponds to 1 frame, starting in the middle of the current frame */
- EnergyTotal = (newLowbandEnergy + h_sbrTransientDetector->prevLowBandEnergy) >> 1;
- EnergyTotal += newHighbandEnergy;
+ /* prevLowBandEnergy: Corresponds to 1 frame, starting with half a frame
+ look-behind newLowbandEnergy: Corresponds to 1 frame, starting in the
+ middle of the current frame */
+ EnergyTotal = (newLowbandEnergy >> 1) +
+ (h_sbrTransientDetector->prevLowBandEnergy >>
+ 1); /* mean of new and prev LB NRG */
+ EnergyTotal =
+ fAddSaturate(EnergyTotal, newHighbandEnergy); /* Add HB NRG */
/* The below border should specify the same position as the middle border
of a FIXFIX-frame with 2 envelopes. */
- border = (sbrSlots+1) >> 1;
-
- if ( (INT)EnergyTotal&0xffffffe0 && (scaleEnergies[0]<32 || scaleEnergies[1]<32) ) /* i.e. > 31 */ {
- delta = spectralChange(EnergiesM,
- scaleEnergies,
- EnergyTotal,
- nSfb,
- 0,
- border,
- YBufferWriteOffset,
- sbrSlots,
- &delta_e
- );
+ border = (sbrSlots + 1) >> 1;
+
+ if ((INT)EnergyTotal & 0xffffffe0 &&
+ (scaleEnergies[0] < 32 || scaleEnergies[1] < 32)) /* i.e. > 31 */ {
+ delta = spectralChange(EnergiesM, scaleEnergies, EnergyTotal, nSfb, 0,
+ border, YBufferWriteOffset, sbrSlots, &delta_e);
} else {
delta = FL2FXCONST_DBL(0.0f);
delta_e = 0;
@@ -437,100 +438,98 @@ FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
*tonality = FL2FXCONST_DBL(0.0f);
}
-
- if ( fIsLessThan(h_sbrTransientDetector->split_thr_m, h_sbrTransientDetector->split_thr_e, delta, delta_e) ) {
+ if (fIsLessThan(h_sbrTransientDetector->split_thr_m,
+ h_sbrTransientDetector->split_thr_e, delta, delta_e)) {
tran_vector[0] = 1; /* Set flag for splitting */
} else {
tran_vector[0] = 0;
}
-
}
/* Update prevLowBandEnergy */
h_sbrTransientDetector->prevLowBandEnergy = newLowbandEnergy;
h_sbrTransientDetector->prevHighBandEnergy = newHighbandEnergy;
- C_ALLOC_SCRATCH_END(_EnergiesM, FIXP_DBL, NUMBER_TIME_SLOTS_2304*MAX_FREQ_COEFFS)
+ C_ALLOC_SCRATCH_END(_EnergiesM, FIXP_DBL,
+ NUMBER_TIME_SLOTS_2304 * MAX_FREQ_COEFFS)
}
}
/*
* Calculate transient energy threshold for each QMF band
*/
-static void
-calculateThresholds(FIXP_DBL **RESTRICT Energies,
- INT *RESTRICT scaleEnergies,
- FIXP_DBL *RESTRICT thresholds,
- int YBufferWriteOffset,
- int YBufferSzShift,
- int noCols,
- int noRows,
- int tran_off)
-{
- FIXP_DBL mean_val,std_val,temp;
+static void calculateThresholds(FIXP_DBL **RESTRICT Energies,
+ INT *RESTRICT scaleEnergies,
+ FIXP_DBL *RESTRICT thresholds,
+ int YBufferWriteOffset, int YBufferSzShift,
+ int noCols, int noRows, int tran_off) {
+ FIXP_DBL mean_val, std_val, temp;
FIXP_DBL i_noCols;
FIXP_DBL i_noCols1;
- FIXP_DBL accu,accu0,accu1;
- int scaleFactor0,scaleFactor1,commonScale;
- int i,j;
+ FIXP_DBL accu, accu0, accu1;
+ int scaleFactor0, scaleFactor1, commonScale;
+ int i, j;
- i_noCols = GetInvInt(noCols + tran_off ) << YBufferSzShift;
+ i_noCols = GetInvInt(noCols + tran_off) << YBufferSzShift;
i_noCols1 = GetInvInt(noCols + tran_off - 1) << YBufferSzShift;
/* calc minimum scale of energies of previous and current frame */
- commonScale = fixMin(scaleEnergies[0],scaleEnergies[1]);
+ commonScale = fixMin(scaleEnergies[0], scaleEnergies[1]);
/* calc scalefactors to adapt energies to common scale */
- scaleFactor0 = fixMin((scaleEnergies[0]-commonScale), (DFRACT_BITS-1));
- scaleFactor1 = fixMin((scaleEnergies[1]-commonScale), (DFRACT_BITS-1));
+ scaleFactor0 = fixMin((scaleEnergies[0] - commonScale), (DFRACT_BITS - 1));
+ scaleFactor1 = fixMin((scaleEnergies[1] - commonScale), (DFRACT_BITS - 1));
FDK_ASSERT((scaleFactor0 >= 0) && (scaleFactor1 >= 0));
/* calculate standard deviation in every subband */
- for (i=0; i<noRows; i++)
- {
- int startEnergy = (tran_off>>YBufferSzShift);
- int endEnergy = ((noCols>>YBufferSzShift)+tran_off);
+ for (i = 0; i < noRows; i++) {
+ int startEnergy = (tran_off >> YBufferSzShift);
+ int endEnergy = ((noCols >> YBufferSzShift) + tran_off);
int shift;
/* calculate mean value over decimated energy values (downsampled by 2). */
accu0 = accu1 = FL2FXCONST_DBL(0.0f);
- for (j=startEnergy; j<YBufferWriteOffset; j++)
- accu0 += fMult(Energies[j][i], i_noCols);
- for (; j<endEnergy; j++)
- accu1 += fMult(Energies[j][i], i_noCols);
+ for (j = startEnergy; j < YBufferWriteOffset; j++)
+ accu0 = fMultAddDiv2(accu0, Energies[j][i], i_noCols);
+ for (; j < endEnergy; j++)
+ accu1 = fMultAddDiv2(accu1, Energies[j][i], i_noCols);
- mean_val = (accu0 >> scaleFactor0) + (accu1 >> scaleFactor1); /* average */
- shift = fixMax(0,CountLeadingBits(mean_val)-6); /* -6 to keep room for accumulating upto N = 24 values */
+ mean_val = ((accu0 << 1) >> scaleFactor0) +
+ ((accu1 << 1) >> scaleFactor1); /* average */
+ shift = fixMax(
+ 0, CountLeadingBits(mean_val) -
+ 6); /* -6 to keep room for accumulating upto N = 24 values */
/* calculate standard deviation */
accu = FL2FXCONST_DBL(0.0f);
/* summe { ((mean_val-nrg)^2) * i_noCols1 } */
- for (j=startEnergy; j<YBufferWriteOffset; j++) {
- temp = ((FIXP_DBL)mean_val - ((FIXP_DBL)Energies[j][i] >> scaleFactor0))<<shift;
- temp = fPow2(temp);
- temp = fMult(temp, i_noCols1);
- accu += temp;
+ for (j = startEnergy; j < YBufferWriteOffset; j++) {
+ temp = ((FIXP_DBL)mean_val - ((FIXP_DBL)Energies[j][i] >> scaleFactor0))
+ << shift;
+ temp = fPow2Div2(temp);
+ accu = fMultAddDiv2(accu, temp, i_noCols1);
}
- for (; j<endEnergy; j++) {
- temp = ((FIXP_DBL)mean_val - ((FIXP_DBL)Energies[j][i] >> scaleFactor1))<<shift;
- temp = fPow2(temp);
- temp = fMult(temp, i_noCols1);
- accu += temp;
+ for (; j < endEnergy; j++) {
+ temp = ((FIXP_DBL)mean_val - ((FIXP_DBL)Energies[j][i] >> scaleFactor1))
+ << shift;
+ temp = fPow2Div2(temp);
+ accu = fMultAddDiv2(accu, temp, i_noCols1);
}
-
- std_val = sqrtFixp(accu)>>shift; /* standard deviation */
+ accu <<= 2;
+ std_val = sqrtFixp(accu) >> shift; /* standard deviation */
/*
Take new threshold as average of calculated standard deviation ratio
and old threshold if greater than absolute threshold
*/
- temp = ( commonScale<=(DFRACT_BITS-1) )
- ? fMult(FL2FXCONST_DBL(0.66f), thresholds[i]) + (fMult(FL2FXCONST_DBL(0.34f), std_val) >> commonScale)
- : (FIXP_DBL) 0;
+ temp = (commonScale <= (DFRACT_BITS - 1))
+ ? fMult(FL2FXCONST_DBL(0.66f), thresholds[i]) +
+ (fMult(FL2FXCONST_DBL(0.34f), std_val) >> commonScale)
+ : (FIXP_DBL)0;
- thresholds[i] = fixMax(ABS_THRES,temp);
+ thresholds[i] = fixMax(ABS_THRES, temp);
FDK_ASSERT(commonScale >= 0);
}
@@ -539,26 +538,17 @@ calculateThresholds(FIXP_DBL **RESTRICT Energies,
/*
* Calculate transient levels for each QMF time slot.
*/
-static void
-extractTransientCandidates(FIXP_DBL **RESTRICT Energies,
- INT *RESTRICT scaleEnergies,
- FIXP_DBL *RESTRICT thresholds,
- FIXP_DBL *RESTRICT transients,
- int YBufferWriteOffset,
- int YBufferSzShift,
- int noCols,
- int start_band,
- int stop_band,
- int tran_off,
- int addPrevSamples)
-{
+static void extractTransientCandidates(
+ FIXP_DBL **RESTRICT Energies, INT *RESTRICT scaleEnergies,
+ FIXP_DBL *RESTRICT thresholds, FIXP_DBL *RESTRICT transients,
+ int YBufferWriteOffset, int YBufferSzShift, int noCols, int start_band,
+ int stop_band, int tran_off, int addPrevSamples) {
FIXP_DBL i_thres;
- C_ALLOC_SCRATCH_START(EnergiesTemp, FIXP_DBL, 2*QMF_MAX_TIME_SLOTS);
- FIXP_DBL *RESTRICT pEnergiesTemp = EnergiesTemp;
+ C_ALLOC_SCRATCH_START(EnergiesTemp, FIXP_DBL, 2 * 32)
int tmpScaleEnergies0, tmpScaleEnergies1;
int endCond;
- int startEnerg,endEnerg;
- int i,j,jIndex,jpBM;
+ int startEnerg, endEnerg;
+ int i, j, jIndex, jpBM;
tmpScaleEnergies0 = scaleEnergies[0];
tmpScaleEnergies1 = scaleEnergies[1];
@@ -571,237 +561,227 @@ extractTransientCandidates(FIXP_DBL **RESTRICT Energies,
FDK_ASSERT((tmpScaleEnergies0 >= 0) && (tmpScaleEnergies1 >= 0));
/* Keep addPrevSamples extra previous transient candidates. */
- FDKmemmove(transients, transients + noCols - addPrevSamples, (tran_off+addPrevSamples) * sizeof (FIXP_DBL));
- FDKmemclear(transients + tran_off + addPrevSamples, noCols * sizeof (FIXP_DBL));
+ FDKmemmove(transients, transients + noCols - addPrevSamples,
+ (tran_off + addPrevSamples) * sizeof(FIXP_DBL));
+ FDKmemclear(transients + tran_off + addPrevSamples,
+ noCols * sizeof(FIXP_DBL));
endCond = noCols; /* Amount of new transient values to be calculated. */
- startEnerg = (tran_off-3)>>YBufferSzShift; /* >>YBufferSzShift because of amount of energy values. -3 because of neighbors being watched. */
- endEnerg = ((noCols+ (YBufferWriteOffset<<YBufferSzShift))-1)>>YBufferSzShift; /* YBufferSzShift shifts because of half energy values. */
-
- /* Compute differential values with two different weightings in every subband */
- for (i=start_band; i<stop_band; i++)
- {
+ startEnerg = (tran_off - 3) >> YBufferSzShift; /* >>YBufferSzShift because of
+ amount of energy values. -3
+ because of neighbors being
+ watched. */
+ endEnerg =
+ ((noCols + (YBufferWriteOffset << YBufferSzShift)) - 1) >>
+ YBufferSzShift; /* YBufferSzShift shifts because of half energy values. */
+
+ /* Compute differential values with two different weightings in every subband
+ */
+ for (i = start_band; i < stop_band; i++) {
FIXP_DBL thres = thresholds[i];
- if((LONG)thresholds[i]>=256)
- i_thres = (LONG)( (LONG)MAXVAL_DBL / ((((LONG)thresholds[i]))+1) )<<(32-24);
+ if ((LONG)thresholds[i] >= 256)
+ i_thres = (LONG)((LONG)MAXVAL_DBL / ((((LONG)thresholds[i])) + 1))
+ << (32 - 24);
else
i_thres = (LONG)MAXVAL_DBL;
/* Copy one timeslot and de-scale and de-squish */
if (YBufferSzShift == 1) {
- for(j=startEnerg; j<YBufferWriteOffset; j++) {
+ for (j = startEnerg; j < YBufferWriteOffset; j++) {
FIXP_DBL tmp = Energies[j][i];
- EnergiesTemp[(j<<1)+1] = EnergiesTemp[j<<1] = tmp>>tmpScaleEnergies0;
+ EnergiesTemp[(j << 1) + 1] = EnergiesTemp[j << 1] =
+ tmp >> tmpScaleEnergies0;
}
- for(; j<=endEnerg; j++) {
+ for (; j <= endEnerg; j++) {
FIXP_DBL tmp = Energies[j][i];
- EnergiesTemp[(j<<1)+1] = EnergiesTemp[j<<1] = tmp>>tmpScaleEnergies1;
+ EnergiesTemp[(j << 1) + 1] = EnergiesTemp[j << 1] =
+ tmp >> tmpScaleEnergies1;
}
} else {
- for(j=startEnerg; j<YBufferWriteOffset; j++) {
+ for (j = startEnerg; j < YBufferWriteOffset; j++) {
FIXP_DBL tmp = Energies[j][i];
- EnergiesTemp[j] = tmp>>tmpScaleEnergies0;
+ EnergiesTemp[j] = tmp >> tmpScaleEnergies0;
}
- for(; j<=endEnerg; j++) {
+ for (; j <= endEnerg; j++) {
FIXP_DBL tmp = Energies[j][i];
- EnergiesTemp[j] = tmp>>tmpScaleEnergies1;
+ EnergiesTemp[j] = tmp >> tmpScaleEnergies1;
}
}
/* Detect peaks in energy values. */
jIndex = tran_off;
- jpBM = jIndex+addPrevSamples;
-
- for (j=endCond; j--; jIndex++, jpBM++)
- {
+ jpBM = jIndex + addPrevSamples;
+ for (j = endCond; j--; jIndex++, jpBM++) {
FIXP_DBL delta, tran;
int d;
delta = (FIXP_DBL)0;
- tran = (FIXP_DBL)0;
+ tran = (FIXP_DBL)0;
- for (d=1; d<4; d++) {
- delta += pEnergiesTemp[jIndex+d]; /* R */
- delta -= pEnergiesTemp[jIndex-d]; /* L */
+ for (d = 1; d < 4; d++) {
+ delta += EnergiesTemp[jIndex + d]; /* R */
+ delta -= EnergiesTemp[jIndex - d]; /* L */
delta -= thres;
- if ( delta > (FIXP_DBL)0 ) {
- tran += fMult(i_thres, delta);
+ if (delta > (FIXP_DBL)0) {
+ tran = fMultAddDiv2(tran, i_thres, delta);
}
}
- transients[jpBM] += tran;
+ transients[jpBM] += (tran << 1);
}
}
- C_ALLOC_SCRATCH_END(EnergiesTemp, FIXP_DBL, 2*QMF_MAX_TIME_SLOTS);
+ C_ALLOC_SCRATCH_END(EnergiesTemp, FIXP_DBL, 2 * 32)
}
-void
-FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTran,
- FIXP_DBL **Energies,
- INT *scaleEnergies,
- UCHAR *transient_info,
- int YBufferWriteOffset,
- int YBufferSzShift,
- int timeStep,
- int frameMiddleBorder)
-{
+void FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTran,
+ FIXP_DBL **Energies, INT *scaleEnergies,
+ UCHAR *transient_info, int YBufferWriteOffset,
+ int YBufferSzShift, int timeStep,
+ int frameMiddleBorder) {
int no_cols = h_sbrTran->no_cols;
int qmfStartSample;
int addPrevSamples;
- int timeStepShift=0;
+ int timeStepShift = 0;
int i, cond;
/* Where to start looking for transients in the transient candidate buffer */
qmfStartSample = timeStep * frameMiddleBorder;
- /* We need to look one value backwards in the transients, so we might need one more previous value. */
- addPrevSamples = (qmfStartSample > 0) ? 0: 1;
+ /* We need to look one value backwards in the transients, so we might need one
+ * more previous value. */
+ addPrevSamples = (qmfStartSample > 0) ? 0 : 1;
switch (timeStep) {
- case 1: timeStepShift = 0; break;
- case 2: timeStepShift = 1; break;
- case 4: timeStepShift = 2; break;
+ case 1:
+ timeStepShift = 0;
+ break;
+ case 2:
+ timeStepShift = 1;
+ break;
+ case 4:
+ timeStepShift = 2;
+ break;
}
- calculateThresholds(Energies,
- scaleEnergies,
- h_sbrTran->thresholds,
- YBufferWriteOffset,
- YBufferSzShift,
- h_sbrTran->no_cols,
- h_sbrTran->no_rows,
- h_sbrTran->tran_off);
-
- extractTransientCandidates(Energies,
- scaleEnergies,
- h_sbrTran->thresholds,
- h_sbrTran->transients,
- YBufferWriteOffset,
- YBufferSzShift,
- h_sbrTran->no_cols,
- 0,
- h_sbrTran->no_rows,
- h_sbrTran->tran_off,
- addPrevSamples );
+ calculateThresholds(Energies, scaleEnergies, h_sbrTran->thresholds,
+ YBufferWriteOffset, YBufferSzShift, h_sbrTran->no_cols,
+ h_sbrTran->no_rows, h_sbrTran->tran_off);
+
+ extractTransientCandidates(
+ Energies, scaleEnergies, h_sbrTran->thresholds, h_sbrTran->transients,
+ YBufferWriteOffset, YBufferSzShift, h_sbrTran->no_cols, 0,
+ h_sbrTran->no_rows, h_sbrTran->tran_off, addPrevSamples);
transient_info[0] = 0;
transient_info[1] = 0;
transient_info[2] = 0;
- /* Offset by the amount of additional previous transient candidates being kept. */
+ /* Offset by the amount of additional previous transient candidates being
+ * kept. */
qmfStartSample += addPrevSamples;
- /* Check for transients in second granule (pick the last value of subsequent values) */
- for (i=qmfStartSample; i<qmfStartSample + no_cols; i++) {
- cond = (h_sbrTran->transients[i] < fMult(FL2FXCONST_DBL(0.9f), h_sbrTran->transients[i - 1]) )
- && (h_sbrTran->transients[i - 1] > h_sbrTran->tran_thr);
+ /* Check for transients in second granule (pick the last value of subsequent
+ * values) */
+ for (i = qmfStartSample; i < qmfStartSample + no_cols; i++) {
+ cond = (h_sbrTran->transients[i] <
+ fMult(FL2FXCONST_DBL(0.9f), h_sbrTran->transients[i - 1])) &&
+ (h_sbrTran->transients[i - 1] > h_sbrTran->tran_thr);
if (cond) {
- transient_info[0] = (i - qmfStartSample)>>timeStepShift;
+ transient_info[0] = (i - qmfStartSample) >> timeStepShift;
transient_info[1] = 1;
break;
}
}
- if ( h_sbrTran->frameShift != 0) {
- /* transient prediction for LDSBR */
- /* Check for transients in first <frameShift> qmf-slots of second frame */
- for (i=qmfStartSample+no_cols; i<qmfStartSample + no_cols+h_sbrTran->frameShift; i++) {
-
- cond = (h_sbrTran->transients[i] < fMult(FL2FXCONST_DBL(0.9f), h_sbrTran->transients[i - 1]) )
- && (h_sbrTran->transients[i - 1] > h_sbrTran->tran_thr);
-
- if (cond) {
- int pos = (int) ( (i - qmfStartSample-no_cols) >> timeStepShift );
- if ((pos < 3) && (transient_info[1]==0)) {
- transient_info[2] = 1;
- }
- break;
+ if (h_sbrTran->frameShift != 0) {
+ /* transient prediction for LDSBR */
+ /* Check for transients in first <frameShift> qmf-slots of second frame */
+ for (i = qmfStartSample + no_cols;
+ i < qmfStartSample + no_cols + h_sbrTran->frameShift; i++) {
+ cond = (h_sbrTran->transients[i] <
+ fMult(FL2FXCONST_DBL(0.9f), h_sbrTran->transients[i - 1])) &&
+ (h_sbrTran->transients[i - 1] > h_sbrTran->tran_thr);
+
+ if (cond) {
+ int pos = (int)((i - qmfStartSample - no_cols) >> timeStepShift);
+ if ((pos < 3) && (transient_info[1] == 0)) {
+ transient_info[2] = 1;
}
+ break;
}
+ }
}
}
-int
-FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
- UINT sbrSyntaxFlags, /* SBR syntax flags derived from AOT. */
- INT frameSize,
- INT sampleFreq,
- sbrConfigurationPtr params,
- int tran_fc,
- int no_cols,
- int no_rows,
- int YBufferWriteOffset,
- int YBufferSzShift,
- int frameShift,
- int tran_off)
-{
- INT totalBitrate = params->codecSettings.standardBitrate * params->codecSettings.nChannels;
- INT codecBitrate = params->codecSettings.bitRate;
- FIXP_DBL bitrateFactor_m, framedur_fix;
- INT bitrateFactor_e, tmp_e;
-
- FDKmemclear(h_sbrTransientDetector,sizeof(SBR_TRANSIENT_DETECTOR));
-
- h_sbrTransientDetector->frameShift = frameShift;
- h_sbrTransientDetector->tran_off = tran_off;
-
- if(codecBitrate) {
- bitrateFactor_m = fDivNorm((FIXP_DBL)totalBitrate, (FIXP_DBL)(codecBitrate<<2),&bitrateFactor_e);
- bitrateFactor_e += 2;
- }
- else {
- bitrateFactor_m = FL2FXCONST_DBL(1.0/4.0);
- bitrateFactor_e = 2;
- }
+int FDKsbrEnc_InitSbrTransientDetector(
+ HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
+ UINT sbrSyntaxFlags, /* SBR syntax flags derived from AOT. */
+ INT frameSize, INT sampleFreq, sbrConfigurationPtr params, int tran_fc,
+ int no_cols, int no_rows, int YBufferWriteOffset, int YBufferSzShift,
+ int frameShift, int tran_off) {
+ INT totalBitrate =
+ params->codecSettings.standardBitrate * params->codecSettings.nChannels;
+ INT codecBitrate = params->codecSettings.bitRate;
+ FIXP_DBL bitrateFactor_m, framedur_fix;
+ INT bitrateFactor_e, tmp_e;
+
+ FDKmemclear(h_sbrTransientDetector, sizeof(SBR_TRANSIENT_DETECTOR));
+
+ h_sbrTransientDetector->frameShift = frameShift;
+ h_sbrTransientDetector->tran_off = tran_off;
+
+ if (codecBitrate) {
+ bitrateFactor_m = fDivNorm((FIXP_DBL)totalBitrate,
+ (FIXP_DBL)(codecBitrate << 2), &bitrateFactor_e);
+ bitrateFactor_e += 2;
+ } else {
+ bitrateFactor_m = FL2FXCONST_DBL(1.0 / 4.0);
+ bitrateFactor_e = 2;
+ }
- framedur_fix = fDivNorm(frameSize, sampleFreq);
+ framedur_fix = fDivNorm(frameSize, sampleFreq);
- /* The longer the frames, the more often should the FIXFIX-
- case transmit 2 envelopes instead of 1.
- Frame durations below 10 ms produce the highest threshold
- so that practically always only 1 env is transmitted. */
- FIXP_DBL tmp = framedur_fix - FL2FXCONST_DBL(0.010);
+ /* The longer the frames, the more often should the FIXFIX-
+ case transmit 2 envelopes instead of 1.
+ Frame durations below 10 ms produce the highest threshold
+ so that practically always only 1 env is transmitted. */
+ FIXP_DBL tmp = framedur_fix - FL2FXCONST_DBL(0.010);
- tmp = fixMax(tmp, FL2FXCONST_DBL(0.0001));
- tmp = fDivNorm(FL2FXCONST_DBL(0.000075), fPow2(tmp), &tmp_e);
+ tmp = fixMax(tmp, FL2FXCONST_DBL(0.0001));
+ tmp = fDivNorm(FL2FXCONST_DBL(0.000075), fPow2(tmp), &tmp_e);
- bitrateFactor_e = (tmp_e + bitrateFactor_e);
+ bitrateFactor_e = (tmp_e + bitrateFactor_e);
- if(sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
+ if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
bitrateFactor_e--; /* divide by 2 */
}
- FDK_ASSERT(no_cols <= QMF_MAX_TIME_SLOTS);
- FDK_ASSERT(no_rows <= QMF_CHANNELS);
+ FDK_ASSERT(no_cols <= 32);
+ FDK_ASSERT(no_rows <= 64);
- h_sbrTransientDetector->no_cols = no_cols;
- h_sbrTransientDetector->tran_thr = (FIXP_DBL)((params->tran_thr << (32-24-1)) / no_rows);
- h_sbrTransientDetector->tran_fc = tran_fc;
- h_sbrTransientDetector->split_thr_m = fMult(tmp, bitrateFactor_m);
- h_sbrTransientDetector->split_thr_e = bitrateFactor_e;
- h_sbrTransientDetector->no_rows = no_rows;
- h_sbrTransientDetector->mode = params->tran_det_mode;
- h_sbrTransientDetector->prevLowBandEnergy = FL2FXCONST_DBL(0.0f);
+ h_sbrTransientDetector->no_cols = no_cols;
+ h_sbrTransientDetector->tran_thr =
+ (FIXP_DBL)((params->tran_thr << (32 - 24 - 1)) / no_rows);
+ h_sbrTransientDetector->tran_fc = tran_fc;
+ h_sbrTransientDetector->split_thr_m = fMult(tmp, bitrateFactor_m);
+ h_sbrTransientDetector->split_thr_e = bitrateFactor_e;
+ h_sbrTransientDetector->no_rows = no_rows;
+ h_sbrTransientDetector->mode = params->tran_det_mode;
+ h_sbrTransientDetector->prevLowBandEnergy = FL2FXCONST_DBL(0.0f);
- return (0);
+ return (0);
}
-
#define ENERGY_SCALING_SIZE 32
INT FDKsbrEnc_InitSbrFastTransientDetector(
- HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
- const INT time_slots_per_frame,
- const INT bandwidth_qmf_slot,
- const INT no_qmf_channels,
- const INT sbr_qmf_1st_band
- )
-{
-
- int i, e;
+ HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
+ const INT time_slots_per_frame, const INT bandwidth_qmf_slot,
+ const INT no_qmf_channels, const INT sbr_qmf_1st_band) {
+ int i;
int buff_size;
FIXP_DBL myExp;
FIXP_DBL myExpSlot;
@@ -809,9 +789,10 @@ INT FDKsbrEnc_InitSbrFastTransientDetector(
h_sbrFastTransientDetector->lookahead = TRAN_DET_LOOKAHEAD;
h_sbrFastTransientDetector->nTimeSlots = time_slots_per_frame;
- buff_size = h_sbrFastTransientDetector->nTimeSlots + h_sbrFastTransientDetector->lookahead;
+ buff_size = h_sbrFastTransientDetector->nTimeSlots +
+ h_sbrFastTransientDetector->lookahead;
- for(i=0; i< buff_size; i++) {
+ for (i = 0; i < buff_size; i++) {
h_sbrFastTransientDetector->delta_energy[i] = FL2FXCONST_DBL(0.0f);
h_sbrFastTransientDetector->energy_timeSlots[i] = FL2FXCONST_DBL(0.0f);
h_sbrFastTransientDetector->lowpass_energy[i] = FL2FXCONST_DBL(0.0f);
@@ -819,77 +800,92 @@ INT FDKsbrEnc_InitSbrFastTransientDetector(
}
FDK_ASSERT(bandwidth_qmf_slot > 0.f);
- h_sbrFastTransientDetector->stopBand = fMin(TRAN_DET_STOP_FREQ/bandwidth_qmf_slot, no_qmf_channels);
- h_sbrFastTransientDetector->startBand = fMin(sbr_qmf_1st_band, h_sbrFastTransientDetector->stopBand - TRAN_DET_MIN_QMFBANDS);
+ h_sbrFastTransientDetector->stopBand =
+ fMin(TRAN_DET_STOP_FREQ / bandwidth_qmf_slot, no_qmf_channels);
+ h_sbrFastTransientDetector->startBand =
+ fMin(sbr_qmf_1st_band,
+ h_sbrFastTransientDetector->stopBand - TRAN_DET_MIN_QMFBANDS);
FDK_ASSERT(h_sbrFastTransientDetector->startBand < no_qmf_channels);
- FDK_ASSERT(h_sbrFastTransientDetector->startBand < h_sbrFastTransientDetector->stopBand);
+ FDK_ASSERT(h_sbrFastTransientDetector->startBand <
+ h_sbrFastTransientDetector->stopBand);
FDK_ASSERT(h_sbrFastTransientDetector->startBand > 1);
FDK_ASSERT(h_sbrFastTransientDetector->stopBand > 1);
/* the energy weighting and adding up has a headroom of 6 Bits,
so up to 64 bands can be added without potential overflow. */
- FDK_ASSERT(h_sbrFastTransientDetector->stopBand - h_sbrFastTransientDetector->startBand <= 64);
-
- /* QMF_HP_dB_SLOPE_FIX says that we want a 20 dB per 16 kHz HP filter.
- The following lines map this to the QMF bandwidth. */
- #define EXP_E 7 /* QMF_CHANNELS (=64) multiplications max, max. allowed sum is 0.5 */
- myExp = fMultNorm(QMF_HP_dBd_SLOPE_FIX, (FIXP_DBL)bandwidth_qmf_slot, &e);
- myExp = scaleValueSaturate(myExp, e+0+DFRACT_BITS-1-EXP_E);
+ FDK_ASSERT(h_sbrFastTransientDetector->stopBand -
+ h_sbrFastTransientDetector->startBand <=
+ 64);
+
+/* QMF_HP_dB_SLOPE_FIX says that we want a 20 dB per 16 kHz HP filter.
+ The following lines map this to the QMF bandwidth. */
+#define EXP_E 7 /* 64 (=64) multiplications max, max. allowed sum is 0.5 */
+ myExp = fMultNorm(QMF_HP_dBd_SLOPE_FIX, 0, (FIXP_DBL)bandwidth_qmf_slot,
+ DFRACT_BITS - 1, EXP_E);
myExpSlot = myExp;
- for(i=0; i<QMF_CHANNELS; i++){
+ for (i = 0; i < 64; i++) {
/* Calculate dBf over all qmf bands:
dBf = (10^(0.002266f/10*bw(slot)))^(band) =
= 2^(log2(10)*0.002266f/10*bw(slot)*band) =
= 2^(0.00075275f*bw(slot)*band) */
- FIXP_DBL dBf_m; /* dBf mantissa */
- INT dBf_e; /* dBf exponent */
+ FIXP_DBL dBf_m; /* dBf mantissa */
+ INT dBf_e; /* dBf exponent */
INT tmp;
- INT dBf_int; /* dBf integer part */
- FIXP_DBL dBf_fract; /* dBf fractional part */
+ INT dBf_int; /* dBf integer part */
+ FIXP_DBL dBf_fract; /* dBf fractional part */
/* myExp*(i+1) = myExp_int - myExp_fract
myExp*(i+1) is split up here for better accuracy of CalcInvLdData(),
for its result can be split up into an integer and a fractional part */
/* Round up to next integer */
- FIXP_DBL myExp_int = (myExpSlot & (FIXP_DBL)0xfe000000) + (FIXP_DBL)0x02000000;
+ FIXP_DBL myExp_int =
+ (myExpSlot & (FIXP_DBL)0xfe000000) + (FIXP_DBL)0x02000000;
/* This is the fractional part that needs to be substracted */
FIXP_DBL myExp_fract = myExp_int - myExpSlot;
/* Calc integer part */
- dBf_int = CalcInvLdData(myExp_int);
- /* The result needs to be re-scaled. The ld(myExp_int) had been scaled by EXP_E,
- the CalcInvLdData expects the operand to be scaled by LD_DATA_SHIFT.
- Therefore, the correctly scaled result is dBf_int^(2^(EXP_E-LD_DATA_SHIFT)),
- which is dBf_int^2 */
- dBf_int *= dBf_int;
-
- /* Calc fractional part */
- dBf_fract = CalcInvLdData(-myExp_fract);
- /* The result needs to be re-scaled. The ld(myExp_fract) had been scaled by EXP_E,
- the CalcInvLdData expects the operand to be scaled by LD_DATA_SHIFT.
- Therefore, the correctly scaled result is dBf_fract^(2^(EXP_E-LD_DATA_SHIFT)),
- which is dBf_fract^2 */
- dBf_fract = fMultNorm(dBf_fract, dBf_fract, &tmp);
-
- /* Get worst case scaling of multiplication result */
- dBf_e = (DFRACT_BITS-1 - tmp) - CountLeadingBits(dBf_int);
-
- /* Now multiply integer with fractional part of the result, thus resulting
- in the overall accurate fractional result */
- dBf_m = fMultNorm(dBf_int, dBf_fract, &e);
- dBf_m = scaleValueSaturate(dBf_m, e+DFRACT_BITS-1+tmp-dBf_e);
- myExpSlot += myExp;
+ dBf_int = CalcInvLdData(myExp_int);
+ /* The result needs to be re-scaled. The ld(myExp_int) had been scaled by
+ EXP_E, the CalcInvLdData expects the operand to be scaled by
+ LD_DATA_SHIFT. Therefore, the correctly scaled result is
+ dBf_int^(2^(EXP_E-LD_DATA_SHIFT)), which is dBf_int^2 */
+
+ if (dBf_int <=
+ 46340) { /* compare with maximum allowed value for signed integer
+ multiplication, 46340 =
+ (INT)floor(sqrt((double)(((UINT)1<<(DFRACT_BITS-1))-1))) */
+ dBf_int *= dBf_int;
+
+ /* Calc fractional part */
+ dBf_fract = CalcInvLdData(-myExp_fract);
+ /* The result needs to be re-scaled. The ld(myExp_fract) had been scaled
+ by EXP_E, the CalcInvLdData expects the operand to be scaled by
+ LD_DATA_SHIFT. Therefore, the correctly scaled result is
+ dBf_fract^(2^(EXP_E-LD_DATA_SHIFT)), which is dBf_fract^2 */
+ dBf_fract = fMultNorm(dBf_fract, dBf_fract, &tmp);
+
+ /* Get worst case scaling of multiplication result */
+ dBf_e = (DFRACT_BITS - 1 - tmp) - CountLeadingBits(dBf_int);
+
+ /* Now multiply integer with fractional part of the result, thus resulting
+ in the overall accurate fractional result */
+ dBf_m = fMultNorm(dBf_int, DFRACT_BITS - 1, dBf_fract, tmp, dBf_e);
+
+ myExpSlot += myExp;
+ } else {
+ dBf_m = (FIXP_DBL)0;
+ dBf_e = 0;
+ }
/* Keep the results */
h_sbrFastTransientDetector->dBf_m[i] = dBf_m;
h_sbrFastTransientDetector->dBf_e[i] = dBf_e;
-
}
/* Make sure that dBf is greater than 1.0 (because it should be a highpass) */
@@ -899,84 +895,91 @@ INT FDKsbrEnc_InitSbrFastTransientDetector(
}
void FDKsbrEnc_fastTransientDetect(
- const HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
- const FIXP_DBL *const *Energies,
- const int *const scaleEnergies,
- const INT YBufferWriteOffset,
- UCHAR *const tran_vector
- )
-{
+ const HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
+ const FIXP_DBL *const *Energies, const int *const scaleEnergies,
+ const INT YBufferWriteOffset, UCHAR *const tran_vector) {
int timeSlot, band;
- FIXP_DBL max_delta_energy; /* helper to store maximum energy ratio */
- int max_delta_energy_scale; /* helper to store scale of maximum energy ratio */
- int ind_max = 0; /* helper to store index of maximum energy ratio */
- int isTransientInFrame = 0;
+ FIXP_DBL max_delta_energy; /* helper to store maximum energy ratio */
+ int max_delta_energy_scale; /* helper to store scale of maximum energy ratio
+ */
+ int ind_max = 0; /* helper to store index of maximum energy ratio */
+ int isTransientInFrame = 0;
- const int nTimeSlots = h_sbrFastTransientDetector->nTimeSlots;
- const int lookahead = h_sbrFastTransientDetector->lookahead;
- const int startBand = h_sbrFastTransientDetector->startBand;
- const int stopBand = h_sbrFastTransientDetector->stopBand;
+ const int nTimeSlots = h_sbrFastTransientDetector->nTimeSlots;
+ const int lookahead = h_sbrFastTransientDetector->lookahead;
+ const int startBand = h_sbrFastTransientDetector->startBand;
+ const int stopBand = h_sbrFastTransientDetector->stopBand;
- int * transientCandidates = h_sbrFastTransientDetector->transientCandidates;
+ int *transientCandidates = h_sbrFastTransientDetector->transientCandidates;
- FIXP_DBL * energy_timeSlots = h_sbrFastTransientDetector->energy_timeSlots;
- int * energy_timeSlots_scale = h_sbrFastTransientDetector->energy_timeSlots_scale;
+ FIXP_DBL *energy_timeSlots = h_sbrFastTransientDetector->energy_timeSlots;
+ int *energy_timeSlots_scale =
+ h_sbrFastTransientDetector->energy_timeSlots_scale;
- FIXP_DBL * delta_energy = h_sbrFastTransientDetector->delta_energy;
- int * delta_energy_scale = h_sbrFastTransientDetector->delta_energy_scale;
+ FIXP_DBL *delta_energy = h_sbrFastTransientDetector->delta_energy;
+ int *delta_energy_scale = h_sbrFastTransientDetector->delta_energy_scale;
- const FIXP_DBL thr = TRAN_DET_THRSHLD;
- const INT thr_scale = TRAN_DET_THRSHLD_SCALE;
+ const FIXP_DBL thr = TRAN_DET_THRSHLD;
+ const INT thr_scale = TRAN_DET_THRSHLD_SCALE;
/*reset transient info*/
tran_vector[2] = 0;
/* reset transient candidates */
- FDKmemclear(transientCandidates+lookahead, nTimeSlots*sizeof(int));
+ FDKmemclear(transientCandidates + lookahead, nTimeSlots * sizeof(int));
- for(timeSlot = lookahead; timeSlot < nTimeSlots + lookahead; timeSlot++) {
+ for (timeSlot = lookahead; timeSlot < nTimeSlots + lookahead; timeSlot++) {
int i, norm;
- FIXP_DBL tmpE = FL2FXCONST_DBL(0.0f);
- int headroomEnSlot = DFRACT_BITS-1;
+ FIXP_DBL tmpE = FL2FXCONST_DBL(0.0f);
+ int headroomEnSlot = DFRACT_BITS - 1;
FIXP_DBL smallNRG = FL2FXCONST_DBL(1e-2f);
FIXP_DBL denominator;
INT denominator_scale;
/* determine minimum headroom of energy values for this timeslot */
- for(band = startBand; band < stopBand; band++) {
- int tmp_headroom = fNormz(Energies[timeSlot][band])-1;
- if(tmp_headroom < headroomEnSlot){
+ for (band = startBand; band < stopBand; band++) {
+ int tmp_headroom = fNormz(Energies[timeSlot][band]) - 1;
+ if (tmp_headroom < headroomEnSlot) {
headroomEnSlot = tmp_headroom;
}
}
- for(i = 0, band = startBand; band < stopBand; band++, i++) {
+ for (i = 0, band = startBand; band < stopBand; band++, i++) {
/* energy is weighted by weightingfactor stored in dBf_m array */
/* dBf_m index runs from 0 to stopBand-startband */
/* energy shifted by calculated headroom for maximum precision */
- FIXP_DBL weightedEnergy = fMult(Energies[timeSlot][band]<<headroomEnSlot, h_sbrFastTransientDetector->dBf_m[i]);
+ FIXP_DBL weightedEnergy =
+ fMult(Energies[timeSlot][band] << headroomEnSlot,
+ h_sbrFastTransientDetector->dBf_m[i]);
/* energy is added up */
/* shift by 6 to have a headroom for maximum 64 additions */
/* shift by dBf_e to handle weighting factor dependent scale factors */
- tmpE += weightedEnergy >> (6 + (10 - h_sbrFastTransientDetector->dBf_e[i]));
+ tmpE +=
+ weightedEnergy >> (6 + (10 - h_sbrFastTransientDetector->dBf_e[i]));
}
/* store calculated energy for timeslot */
energy_timeSlots[timeSlot] = tmpE;
- /* calculate overall scale factor for energy of this timeslot */
- /* = original scale factor of energies (-scaleEnergies[0]+2*QMF_SCALE_OFFSET or -scaleEnergies[1]+2*QMF_SCALE_OFFSET */
- /* depending on YBufferWriteOffset) */
- /* + weighting factor scale (10) */
- /* + adding up scale factor ( 6) */
- /* - headroom of energy value (headroomEnSlot) */
- if(timeSlot < YBufferWriteOffset){
- energy_timeSlots_scale[timeSlot] = (-scaleEnergies[0]+2*QMF_SCALE_OFFSET) + (10+6) - headroomEnSlot;
+ /* calculate overall scale factor for energy of this timeslot */
+ /* = original scale factor of energies
+ * (-scaleEnergies[0]+2*QMF_SCALE_OFFSET or
+ * -scaleEnergies[1]+2*QMF_SCALE_OFFSET */
+ /* depending on YBufferWriteOffset) */
+ /* + weighting factor scale (10) */
+ /* + adding up scale factor ( 6) */
+ /* - headroom of energy value (headroomEnSlot) */
+ if (timeSlot < YBufferWriteOffset) {
+ energy_timeSlots_scale[timeSlot] =
+ (-scaleEnergies[0] + 2 * QMF_SCALE_OFFSET) + (10 + 6) -
+ headroomEnSlot;
} else {
- energy_timeSlots_scale[timeSlot] = (-scaleEnergies[1]+2*QMF_SCALE_OFFSET) + (10+6) - headroomEnSlot;
+ energy_timeSlots_scale[timeSlot] =
+ (-scaleEnergies[1] + 2 * QMF_SCALE_OFFSET) + (10 + 6) -
+ headroomEnSlot;
}
/* Add a small energy to the denominator, thus making the transient
@@ -984,19 +987,21 @@ void FDKsbrEnc_fastTransientDetect(
silent ones not. */
/* make sure that smallNRG does not overflow */
- if ( -energy_timeSlots_scale[timeSlot-1] + 1 > 5 )
- {
+ if (-energy_timeSlots_scale[timeSlot - 1] + 1 > 5) {
denominator = smallNRG;
denominator_scale = 0;
} else {
/* Leave an additional headroom of 1 bit for this addition. */
- smallNRG = scaleValue(smallNRG, -(energy_timeSlots_scale[timeSlot-1] + 1));
- denominator = (energy_timeSlots[timeSlot-1]>>1) + smallNRG;
- denominator_scale = energy_timeSlots_scale[timeSlot-1]+1;
+ smallNRG =
+ scaleValue(smallNRG, -(energy_timeSlots_scale[timeSlot - 1] + 1));
+ denominator = (energy_timeSlots[timeSlot - 1] >> 1) + smallNRG;
+ denominator_scale = energy_timeSlots_scale[timeSlot - 1] + 1;
}
- delta_energy[timeSlot] = fDivNorm(energy_timeSlots[timeSlot], denominator, &norm);
- delta_energy_scale[timeSlot] = energy_timeSlots_scale[timeSlot] - denominator_scale + norm;
+ delta_energy[timeSlot] =
+ fDivNorm(energy_timeSlots[timeSlot], denominator, &norm);
+ delta_energy_scale[timeSlot] =
+ energy_timeSlots_scale[timeSlot] - denominator_scale + norm;
}
/*get transient candidates*/
@@ -1008,15 +1013,21 @@ void FDKsbrEnc_fastTransientDetect(
last or the one before the last slot, it is marked as a transient.*/
FDK_ASSERT(lookahead >= 2);
- for(timeSlot = lookahead; timeSlot < nTimeSlots + lookahead; timeSlot++) {
- FIXP_DBL energy_cur_slot_weighted = fMult(energy_timeSlots[timeSlot],FL2FXCONST_DBL(1.0f/1.4f));
- if( !fIsLessThan(delta_energy[timeSlot], delta_energy_scale[timeSlot], thr, thr_scale) &&
- ( ((transientCandidates[timeSlot-2]==0) && (transientCandidates[timeSlot-1]==0)) ||
- !fIsLessThan(energy_cur_slot_weighted, energy_timeSlots_scale[timeSlot], energy_timeSlots[timeSlot-1], energy_timeSlots_scale[timeSlot-1] ) ||
- !fIsLessThan(energy_cur_slot_weighted, energy_timeSlots_scale[timeSlot], energy_timeSlots[timeSlot-2], energy_timeSlots_scale[timeSlot-2] )
- )
- )
-{
+ for (timeSlot = lookahead; timeSlot < nTimeSlots + lookahead; timeSlot++) {
+ FIXP_DBL energy_cur_slot_weighted =
+ fMult(energy_timeSlots[timeSlot], FL2FXCONST_DBL(1.0f / 1.4f));
+ if (!fIsLessThan(delta_energy[timeSlot], delta_energy_scale[timeSlot], thr,
+ thr_scale) &&
+ (((transientCandidates[timeSlot - 2] == 0) &&
+ (transientCandidates[timeSlot - 1] == 0)) ||
+ !fIsLessThan(energy_cur_slot_weighted,
+ energy_timeSlots_scale[timeSlot],
+ energy_timeSlots[timeSlot - 1],
+ energy_timeSlots_scale[timeSlot - 1]) ||
+ !fIsLessThan(energy_cur_slot_weighted,
+ energy_timeSlots_scale[timeSlot],
+ energy_timeSlots[timeSlot - 2],
+ energy_timeSlots_scale[timeSlot - 2]))) {
/* in case of strong transients, subsequent
* qmf slots might be recognized as transients. */
transientCandidates[timeSlot] = 1;
@@ -1024,22 +1035,24 @@ void FDKsbrEnc_fastTransientDetect(
}
/*get transient with max energy*/
- max_delta_energy = FL2FXCONST_DBL(0.0f);
+ max_delta_energy = FL2FXCONST_DBL(0.0f);
max_delta_energy_scale = 0;
ind_max = 0;
isTransientInFrame = 0;
- for(timeSlot = 0; timeSlot < nTimeSlots; timeSlot++) {
+ for (timeSlot = 0; timeSlot < nTimeSlots; timeSlot++) {
int scale = fMax(delta_energy_scale[timeSlot], max_delta_energy_scale);
- if(transientCandidates[timeSlot] && ( (delta_energy[timeSlot] >> (scale - delta_energy_scale[timeSlot])) > (max_delta_energy >> (scale - max_delta_energy_scale)) ) ) {
- max_delta_energy = delta_energy[timeSlot];
+ if (transientCandidates[timeSlot] &&
+ ((delta_energy[timeSlot] >> (scale - delta_energy_scale[timeSlot])) >
+ (max_delta_energy >> (scale - max_delta_energy_scale)))) {
+ max_delta_energy = delta_energy[timeSlot];
max_delta_energy_scale = scale;
- ind_max = timeSlot;
+ ind_max = timeSlot;
isTransientInFrame = 1;
}
}
/*from all transient candidates take the one with the biggest energy*/
- if(isTransientInFrame) {
+ if (isTransientInFrame) {
tran_vector[0] = ind_max;
tran_vector[1] = 1;
} else {
@@ -1048,22 +1061,22 @@ void FDKsbrEnc_fastTransientDetect(
}
/*check for transients in lookahead*/
- for(timeSlot = nTimeSlots; timeSlot < nTimeSlots + lookahead; timeSlot++) {
- if(transientCandidates[timeSlot]) {
+ for (timeSlot = nTimeSlots; timeSlot < nTimeSlots + lookahead; timeSlot++) {
+ if (transientCandidates[timeSlot]) {
tran_vector[2] = 1;
}
}
/*update buffers*/
- for(timeSlot = 0; timeSlot < lookahead; timeSlot++) {
+ for (timeSlot = 0; timeSlot < lookahead; timeSlot++) {
transientCandidates[timeSlot] = transientCandidates[nTimeSlots + timeSlot];
/* fixpoint stuff */
- energy_timeSlots[timeSlot] = energy_timeSlots[nTimeSlots + timeSlot];
- energy_timeSlots_scale[timeSlot] = energy_timeSlots_scale[nTimeSlots + timeSlot];
+ energy_timeSlots[timeSlot] = energy_timeSlots[nTimeSlots + timeSlot];
+ energy_timeSlots_scale[timeSlot] =
+ energy_timeSlots_scale[nTimeSlots + timeSlot];
- delta_energy[timeSlot] = delta_energy[nTimeSlots + timeSlot];
- delta_energy_scale[timeSlot] = delta_energy_scale[nTimeSlots + timeSlot];
+ delta_energy[timeSlot] = delta_energy[nTimeSlots + timeSlot];
+ delta_energy_scale[timeSlot] = delta_energy_scale[nTimeSlots + timeSlot];
}
}
-