aboutsummaryrefslogtreecommitdiffstats
path: root/libSBRenc/src/sbr_encoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libSBRenc/src/sbr_encoder.cpp')
-rw-r--r--libSBRenc/src/sbr_encoder.cpp2868
1 files changed, 1501 insertions, 1367 deletions
diff --git a/libSBRenc/src/sbr_encoder.cpp b/libSBRenc/src/sbr_encoder.cpp
index 71aab78..df9e996 100644
--- a/libSBRenc/src/sbr_encoder.cpp
+++ b/libSBRenc/src/sbr_encoder.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,20 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
+
+/**************************** SBR encoder library ******************************
-/*************************** Fraunhofer IIS FDK Tools ***********************
+ Author(s): Andreas Ehret, Tobias Chalupka
- Author(s): Andreas Ehret, Tobias Chalupka
Description: SBR encoder top level processing.
-******************************************************************************/
+*******************************************************************************/
#include "sbr_encoder.h"
-#include "sbr_ram.h"
-#include "sbr_rom.h"
+#include "sbrenc_ram.h"
+#include "sbrenc_rom.h"
#include "sbrenc_freq_sca.h"
#include "env_bit.h"
#include "cmondata.h"
@@ -101,11 +113,9 @@ amm-info@iis.fraunhofer.de
#include "ps_main.h"
-#define SBRENCODER_LIB_VL0 3
-#define SBRENCODER_LIB_VL1 3
-#define SBRENCODER_LIB_VL2 12
-
-
+#define SBRENCODER_LIB_VL0 4
+#define SBRENCODER_LIB_VL1 0
+#define SBRENCODER_LIB_VL2 0
/***************************************************************************/
/*
@@ -119,34 +129,83 @@ amm-info@iis.fraunhofer.de
(core2sbr delay ) ds (read, core and ds area)
*/
-#define SFB(dwnsmp) (32 << (dwnsmp-1)) /* SBR Frequency bands: 64 for dual-rate, 32 for single-rate */
-#define STS(fl) (((fl)==1024)?32:30) /* SBR Time Slots: 32 for core frame length 1024, 30 for core frame length 960 */
-
-#define DELAY_QMF_ANA(dwnsmp) ((320<<((dwnsmp)-1)) - (32<<((dwnsmp)-1))) /* Full bandwidth */
-#define DELAY_HYB_ANA (10*64) /* + 0.5 */ /* */
-#define DELAY_HYB_SYN (6*64 - 32) /* */
-#define DELAY_QMF_POSTPROC(dwnsmp) (32*(dwnsmp)) /* QMF postprocessing delay */
-#define DELAY_DEC_QMF(dwnsmp) (6 * SFB(dwnsmp) ) /* Decoder QMF overlap */
-#define DELAY_QMF_SYN (2) /* NO_POLY/2=2.5, rounded down to 2 */
-#define DELAY_QMF_DS (32) /* QMF synthesis for downsampled time signal */
+#define SFB(dwnsmp) \
+ (32 << (dwnsmp - \
+ 1)) /* SBR Frequency bands: 64 for dual-rate, 32 for single-rate */
+#define STS(fl) \
+ (((fl) == 1024) ? 32 \
+ : 30) /* SBR Time Slots: 32 for core frame length 1024, 30 \
+ for core frame length 960 */
+
+#define DELAY_QMF_ANA(dwnsmp) \
+ ((320 << ((dwnsmp)-1)) - (32 << ((dwnsmp)-1))) /* Full bandwidth */
+#define DELAY_HYB_ANA (10 * 64) /* + 0.5 */ /* */
+#define DELAY_HYB_SYN (6 * 64 - 32) /* */
+#define DELAY_QMF_POSTPROC(dwnsmp) \
+ (32 * (dwnsmp)) /* QMF postprocessing delay */
+#define DELAY_DEC_QMF(dwnsmp) (6 * SFB(dwnsmp)) /* Decoder QMF overlap */
+#define DELAY_QMF_SYN(dwnsmp) \
+ (1 << (dwnsmp - \
+ 1)) /* QMF_NO_POLY/2=2.5, rounded down to 2, half for single-rate */
+#define DELAY_QMF_DS (32) /* QMF synthesis for downsampled time signal */
/* Delay in QMF paths */
-#define DELAY_SBR(fl,dwnsmp) (DELAY_QMF_ANA(dwnsmp) + (SFB(dwnsmp)*STS(fl) - 1) + DELAY_QMF_SYN)
-#define DELAY_PS(fl,dwnsmp) (DELAY_QMF_ANA(dwnsmp) + DELAY_HYB_ANA + DELAY_DEC_QMF(dwnsmp) + (SFB(dwnsmp)*STS(fl)-1) + DELAY_HYB_SYN + DELAY_QMF_SYN)
-#define DELAY_ELDSBR(fl,dwnsmp) ( ( ((fl)/2)*(dwnsmp) ) - 1 + DELAY_QMF_POSTPROC(dwnsmp) )
-
-/* Delay differences for SBR and SBR+PS */
-#define MAX_DS_FILTER_DELAY (5) /* the additional max downsampler filter delay (source fs) */
-#define DELAY_AAC2SBR(fl,dwnsmp) ((DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_QMF_SYN) - DELAY_SBR((fl),(dwnsmp)))
-#define DELAY_ELD2SBR(fl,dwnsmp) ((DELAY_QMF_POSTPROC(dwnsmp)) - DELAY_ELDSBR(fl,dwnsmp))
-#define DELAY_AAC2PS(fl,dwnsmp) ((DELAY_QMF_ANA(dwnsmp) + DELAY_QMF_DS + /*(DELAY_AAC(fl)*2) + */ DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_HYB_SYN + DELAY_QMF_SYN) - DELAY_PS(fl,dwnsmp)) /* 2048 - 463*2 */
-
-/* Assumption: The sample delay resulting of of DELAY_AAC2PS is always smaller than the sample delay implied by DELAY_AAC2SBR */
-#define MAX_SAMPLE_DELAY (DELAY_AAC2SBR(1024,2) + MAX_DS_FILTER_DELAY) /* maximum delay: frame length of 1024 and dual-rate sbr */
+#define DELAY_SBR(fl, dwnsmp) \
+ (DELAY_QMF_ANA(dwnsmp) + (SFB(dwnsmp) * STS(fl) - 1) + DELAY_QMF_SYN(dwnsmp))
+#define DELAY_PS(fl, dwnsmp) \
+ (DELAY_QMF_ANA(dwnsmp) + DELAY_HYB_ANA + DELAY_DEC_QMF(dwnsmp) + \
+ (SFB(dwnsmp) * STS(fl) - 1) + DELAY_HYB_SYN + DELAY_QMF_SYN(dwnsmp))
+#define DELAY_ELDSBR(fl, dwnsmp) \
+ ((((fl) / 2) * (dwnsmp)) - 1 + DELAY_QMF_POSTPROC(dwnsmp))
+#define DELAY_ELDv2SBR(fl, dwnsmp) \
+ ((((fl) / 2) * (dwnsmp)) - 1 + 80 * (dwnsmp)) /* 80 is the delay caused \
+ by the sum of the CLD \
+ analysis and the MPSLD \
+ synthesis filterbank */
+
+/* Delay in core path (core and downsampler not taken into account) */
+#define DELAY_COREPATH_SBR(fl, dwnsmp) \
+ ((DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_QMF_SYN(dwnsmp)))
+#define DELAY_COREPATH_ELDSBR(fl, dwnsmp) ((DELAY_QMF_POSTPROC(dwnsmp)))
+#define DELAY_COREPATH_ELDv2SBR(fl, dwnsmp) (128 * (dwnsmp)) /* 4 slots */
+#define DELAY_COREPATH_PS(fl, dwnsmp) \
+ ((DELAY_QMF_ANA(dwnsmp) + DELAY_QMF_DS + \
+ /*(DELAY_AAC(fl)*2) + */ DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + \
+ DELAY_HYB_SYN + DELAY_QMF_SYN(dwnsmp))) /* 2048 - 463*2 */
+
+/* Delay differences between SBR- and downsampled path for SBR and SBR+PS */
+#define DELAY_AAC2SBR(fl, dwnsmp) \
+ ((DELAY_COREPATH_SBR(fl, dwnsmp)) - DELAY_SBR((fl), (dwnsmp)))
+#define DELAY_ELD2SBR(fl, dwnsmp) \
+ ((DELAY_COREPATH_ELDSBR(fl, dwnsmp)) - DELAY_ELDSBR(fl, dwnsmp))
+#define DELAY_AAC2PS(fl, dwnsmp) \
+ ((DELAY_COREPATH_PS(fl, dwnsmp)) - DELAY_PS(fl, dwnsmp)) /* 2048 - 463*2 */
+
+/* Assumption: The sample delay resulting of of DELAY_AAC2PS is always smaller
+ * than the sample delay implied by DELAY_AAC2SBR */
+#define MAX_DS_FILTER_DELAY \
+ (5) /* the additional max downsampler filter delay (source fs) */
+#define MAX_SAMPLE_DELAY \
+ (DELAY_AAC2SBR(1024, 2) + MAX_DS_FILTER_DELAY) /* maximum delay: frame \
+ length of 1024 and \
+ dual-rate sbr */
/***************************************************************************/
-
+/*************** Delay parameters for sbrEncoder_Init_delay() **************/
+typedef struct {
+ int dsDelay; /* the delay of the (time-domain) downsampler itself */
+ int delay; /* overall delay / samples */
+ int sbrDecDelay; /* SBR decoder's delay */
+ int corePathOffset; /* core path offset / samples; added by
+ sbrEncoder_Init_delay() */
+ int sbrPathOffset; /* SBR path offset / samples; added by
+ sbrEncoder_Init_delay() */
+ int bitstrDelay; /* bitstream delay / frames; added by sbrEncoder_Init_delay()
+ */
+ int delayInput2Core; /* delay of the input to the core / samples */
+} DELAY_PARAM;
+/***************************************************************************/
#define INVALID_TABLE_IDX -1
@@ -160,44 +219,38 @@ amm-info@iis.fraunhofer.de
****************************************************************************/
#define DISTANCE_CEIL_VALUE 5000000
-static INT
-getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */
- UINT numChannels,/*! the number of channels for the core coder */
- UINT sampleRate, /*! the sampling rate of the core coder */
- AUDIO_OBJECT_TYPE core,
- UINT *pBitRateClosest
- )
-{
- int i, bitRateClosestLowerIndex=-1, bitRateClosestUpperIndex=-1, found = 0;
- UINT bitRateClosestUpper = 0, bitRateClosestLower=DISTANCE_CEIL_VALUE;
-
- #define isForThisCore(i) \
- ( ( sbrTuningTable[i].coreCoder == CODEC_AACLD && core == AOT_ER_AAC_ELD ) || \
- ( sbrTuningTable[i].coreCoder == CODEC_AAC && core != AOT_ER_AAC_ELD ) )
-
- for (i=0; i < sbrTuningTableSize ; i++) {
- if ( isForThisCore(i) ) /* tuning table is for this core codec */
+static INT getSbrTuningTableIndex(
+ UINT bitrate, /*! the total bitrate in bits/sec */
+ UINT numChannels, /*! the number of channels for the core coder */
+ UINT sampleRate, /*! the sampling rate of the core coder */
+ AUDIO_OBJECT_TYPE core, UINT *pBitRateClosest) {
+ int i, bitRateClosestLowerIndex = -1, bitRateClosestUpperIndex = -1,
+ found = 0;
+ UINT bitRateClosestUpper = 0, bitRateClosestLower = DISTANCE_CEIL_VALUE;
+
+#define isForThisCore(i) \
+ ((sbrTuningTable[i].coreCoder == CODEC_AACLD && core == AOT_ER_AAC_ELD) || \
+ (sbrTuningTable[i].coreCoder == CODEC_AAC && core != AOT_ER_AAC_ELD))
+
+ for (i = 0; i < sbrTuningTableSize; i++) {
+ if (isForThisCore(i)) /* tuning table is for this core codec */
{
- if ( numChannels == sbrTuningTable [i].numChannels
- && sampleRate == sbrTuningTable [i].sampleRate )
- {
+ if (numChannels == sbrTuningTable[i].numChannels &&
+ sampleRate == sbrTuningTable[i].sampleRate) {
found = 1;
- if ((bitrate >= sbrTuningTable [i].bitrateFrom) &&
- (bitrate < sbrTuningTable [i].bitrateTo)) {
- bitRateClosestLower = bitrate;
- bitRateClosestUpper = bitrate;
- //FDKprintf("entry %d\n", i);
- return i ;
+ if ((bitrate >= sbrTuningTable[i].bitrateFrom) &&
+ (bitrate < sbrTuningTable[i].bitrateTo)) {
+ return i;
} else {
- if ( sbrTuningTable [i].bitrateFrom > bitrate ) {
- if (sbrTuningTable [i].bitrateFrom < bitRateClosestLower) {
- bitRateClosestLower = sbrTuningTable [i].bitrateFrom;
+ if (sbrTuningTable[i].bitrateFrom > bitrate) {
+ if (sbrTuningTable[i].bitrateFrom < bitRateClosestLower) {
+ bitRateClosestLower = sbrTuningTable[i].bitrateFrom;
bitRateClosestLowerIndex = i;
}
}
- if ( sbrTuningTable [i].bitrateTo <= bitrate ) {
- if (sbrTuningTable [i].bitrateTo > bitRateClosestUpper) {
- bitRateClosestUpper = sbrTuningTable [i].bitrateTo-1;
+ if (sbrTuningTable[i].bitrateTo <= bitrate) {
+ if (sbrTuningTable[i].bitrateTo > bitRateClosestUpper) {
+ bitRateClosestUpper = sbrTuningTable[i].bitrateTo - 1;
bitRateClosestUpperIndex = i;
}
}
@@ -206,20 +259,25 @@ getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */
}
}
- if (pBitRateClosest != NULL)
- {
- /* If there was at least one matching tuning entry found then pick the least distance bit rate */
- if (found)
- {
- int distanceUpper=DISTANCE_CEIL_VALUE, distanceLower=DISTANCE_CEIL_VALUE;
+ if (bitRateClosestUpperIndex >= 0) {
+ return bitRateClosestUpperIndex;
+ }
+
+ if (pBitRateClosest != NULL) {
+ /* If there was at least one matching tuning entry pick the least distance
+ * bit rate */
+ if (found) {
+ int distanceUpper = DISTANCE_CEIL_VALUE,
+ distanceLower = DISTANCE_CEIL_VALUE;
if (bitRateClosestLowerIndex >= 0) {
- distanceLower = sbrTuningTable [bitRateClosestLowerIndex].bitrateFrom - bitrate;
+ distanceLower =
+ sbrTuningTable[bitRateClosestLowerIndex].bitrateFrom - bitrate;
}
if (bitRateClosestUpperIndex >= 0) {
- distanceUpper = bitrate - sbrTuningTable [bitRateClosestUpperIndex].bitrateTo;
+ distanceUpper =
+ bitrate - sbrTuningTable[bitRateClosestUpperIndex].bitrateTo;
}
- if ( distanceUpper < distanceLower )
- {
+ if (distanceUpper < distanceLower) {
*pBitRateClosest = bitRateClosestUpper;
} else {
*pBitRateClosest = bitRateClosestLower;
@@ -241,44 +299,47 @@ getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */
\return Index to the appropriate table
****************************************************************************/
-static INT
-getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest){
-
- INT i, paramSets = sizeof (psTuningTable) / sizeof (psTuningTable [0]);
- int bitRateClosestLowerIndex=-1, bitRateClosestUpperIndex=-1;
- UINT bitRateClosestUpper = 0, bitRateClosestLower=DISTANCE_CEIL_VALUE;
-
- for (i = 0 ; i < paramSets ; i++) {
- if ((bitrate >= psTuningTable [i].bitrateFrom) &&
- (bitrate < psTuningTable [i].bitrateTo)) {
- return i ;
+static INT getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest) {
+ INT i, paramSets = sizeof(psTuningTable) / sizeof(psTuningTable[0]);
+ int bitRateClosestLowerIndex = -1, bitRateClosestUpperIndex = -1;
+ UINT bitRateClosestUpper = 0, bitRateClosestLower = DISTANCE_CEIL_VALUE;
+
+ for (i = 0; i < paramSets; i++) {
+ if ((bitrate >= psTuningTable[i].bitrateFrom) &&
+ (bitrate < psTuningTable[i].bitrateTo)) {
+ return i;
} else {
- if ( psTuningTable [i].bitrateFrom > bitrate ) {
- if (psTuningTable [i].bitrateFrom < bitRateClosestLower) {
- bitRateClosestLower = psTuningTable [i].bitrateFrom;
+ if (psTuningTable[i].bitrateFrom > bitrate) {
+ if (psTuningTable[i].bitrateFrom < bitRateClosestLower) {
+ bitRateClosestLower = psTuningTable[i].bitrateFrom;
bitRateClosestLowerIndex = i;
}
}
- if ( psTuningTable [i].bitrateTo <= bitrate ) {
- if (psTuningTable [i].bitrateTo > bitRateClosestUpper) {
- bitRateClosestUpper = psTuningTable [i].bitrateTo-1;
+ if (psTuningTable[i].bitrateTo <= bitrate) {
+ if (psTuningTable[i].bitrateTo > bitRateClosestUpper) {
+ bitRateClosestUpper = psTuningTable[i].bitrateTo - 1;
bitRateClosestUpperIndex = i;
}
}
}
}
- if (pBitRateClosest != NULL)
- {
- int distanceUpper=DISTANCE_CEIL_VALUE, distanceLower=DISTANCE_CEIL_VALUE;
+ if (bitRateClosestUpperIndex >= 0) {
+ return bitRateClosestUpperIndex;
+ }
+
+ if (pBitRateClosest != NULL) {
+ int distanceUpper = DISTANCE_CEIL_VALUE,
+ distanceLower = DISTANCE_CEIL_VALUE;
if (bitRateClosestLowerIndex >= 0) {
- distanceLower = sbrTuningTable [bitRateClosestLowerIndex].bitrateFrom - bitrate;
+ distanceLower =
+ sbrTuningTable[bitRateClosestLowerIndex].bitrateFrom - bitrate;
}
if (bitRateClosestUpperIndex >= 0) {
- distanceUpper = bitrate - sbrTuningTable [bitRateClosestUpperIndex].bitrateTo;
+ distanceUpper =
+ bitrate - sbrTuningTable[bitRateClosestUpperIndex].bitrateTo;
}
- if ( distanceUpper < distanceLower )
- {
+ if (distanceUpper < distanceLower) {
*pBitRateClosest = bitRateClosestUpper;
} else {
*pBitRateClosest = bitRateClosestLower;
@@ -300,41 +361,29 @@ getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest){
\ingroup SbrEncCfg
****************************************************************************/
-static INT
-FDKsbrEnc_GetDownsampledStopFreq (
- const INT sampleRateCore,
- const INT startFreq,
- INT stopFreq,
- const INT downSampleFactor
- )
-{
+static INT FDKsbrEnc_GetDownsampledStopFreq(const INT sampleRateCore,
+ const INT startFreq, INT stopFreq,
+ const INT downSampleFactor) {
INT maxStopFreqRaw = sampleRateCore / 2;
INT startBand, stopBand;
HANDLE_ERROR_INFO err;
- while (stopFreq > 0 && FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) > maxStopFreqRaw) {
+ while (stopFreq > 0 && FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) >
+ maxStopFreqRaw) {
stopFreq--;
}
- if (FDKsbrEnc_getSbrStopFreqRAW( stopFreq, sampleRateCore) > maxStopFreqRaw)
+ if (FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) > maxStopFreqRaw)
return -1;
- err = FDKsbrEnc_FindStartAndStopBand (
- sampleRateCore<<(downSampleFactor-1),
- sampleRateCore,
- 32<<(downSampleFactor-1),
- startFreq,
- stopFreq,
- &startBand,
- &stopBand
- );
- if (err)
- return -1;
+ err = FDKsbrEnc_FindStartAndStopBand(
+ sampleRateCore << (downSampleFactor - 1), sampleRateCore,
+ 32 << (downSampleFactor - 1), startFreq, stopFreq, &startBand, &stopBand);
+ if (err) return -1;
return stopFreq;
}
-
/***************************************************************************/
/*!
@@ -345,22 +394,18 @@ FDKsbrEnc_GetDownsampledStopFreq (
\return a flag indicating success: yes (1) or no (0)
****************************************************************************/
-static UINT
-FDKsbrEnc_IsSbrSettingAvail (
- UINT bitrate, /*! the total bitrate in bits/sec */
- UINT vbrMode, /*! the vbr paramter, 0 means constant bitrate */
- UINT numOutputChannels, /*! the number of channels for the core coder */
- UINT sampleRateInput, /*! the input sample rate [in Hz] */
- UINT sampleRateCore, /*! the core's sampling rate */
- AUDIO_OBJECT_TYPE core
- )
-{
+static UINT FDKsbrEnc_IsSbrSettingAvail(
+ UINT bitrate, /*! the total bitrate in bits/sec */
+ UINT vbrMode, /*! the vbr paramter, 0 means constant bitrate */
+ UINT numOutputChannels, /*! the number of channels for the core coder */
+ UINT sampleRateInput, /*! the input sample rate [in Hz] */
+ UINT sampleRateCore, /*! the core's sampling rate */
+ AUDIO_OBJECT_TYPE core) {
INT idx = INVALID_TABLE_IDX;
- if (sampleRateInput < 16000)
- return 0;
+ if (sampleRateInput < 16000) return 0;
- if (bitrate==0) {
+ if (bitrate == 0) {
/* map vbr quality to bitrate */
if (vbrMode < 30)
bitrate = 24000;
@@ -375,12 +420,12 @@ FDKsbrEnc_IsSbrSettingAvail (
bitrate *= numOutputChannels;
}
- idx = getSbrTuningTableIndex(bitrate, numOutputChannels, sampleRateCore, core, NULL);
+ idx = getSbrTuningTableIndex(bitrate, numOutputChannels, sampleRateCore, core,
+ NULL);
return (idx == INVALID_TABLE_IDX ? 0 : 1);
}
-
/***************************************************************************/
/*!
@@ -390,46 +435,46 @@ FDKsbrEnc_IsSbrSettingAvail (
\return A flag indicating success: yes (1) or no (0)
****************************************************************************/
-static UINT
-FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modified */
- UINT bitRate, /*! the total bitrate in bits/sec */
- UINT numChannels, /*! the core coder number of channels */
- UINT sampleRateCore, /*! the core coder sampling rate in Hz */
- UINT sampleRateSbr, /*! the sbr coder sampling rate in Hz */
- UINT transFac, /*! the short block to long block ratio */
- UINT standardBitrate, /*! the standard bitrate per channel in bits/sec */
- UINT vbrMode, /*! the vbr paramter, 0 poor quality .. 100 high quality*/
- UINT useSpeechConfig, /*!< adapt tuning parameters for speech ? */
- UINT lcsMode, /*! the low complexity stereo mode */
- UINT bParametricStereo, /*!< use parametric stereo */
- AUDIO_OBJECT_TYPE core) /* Core audio codec object type */
+static UINT FDKsbrEnc_AdjustSbrSettings(
+ const sbrConfigurationPtr config, /*! output, modified */
+ UINT bitRate, /*! the total bitrate in bits/sec */
+ UINT numChannels, /*! the core coder number of channels */
+ UINT sampleRateCore, /*! the core coder sampling rate in Hz */
+ UINT sampleRateSbr, /*! the sbr coder sampling rate in Hz */
+ UINT transFac, /*! the short block to long block ratio */
+ UINT standardBitrate, /*! the standard bitrate per channel in bits/sec */
+ UINT vbrMode, /*! the vbr paramter, 0 poor quality .. 100 high quality*/
+ UINT useSpeechConfig, /*!< adapt tuning parameters for speech ? */
+ UINT lcsMode, /*! the low complexity stereo mode */
+ UINT bParametricStereo, /*!< use parametric stereo */
+ AUDIO_OBJECT_TYPE core) /* Core audio codec object type */
{
INT idx = INVALID_TABLE_IDX;
/* set the core codec settings */
- config->codecSettings.bitRate = bitRate;
- config->codecSettings.nChannels = numChannels;
- config->codecSettings.sampleFreq = sampleRateCore;
- config->codecSettings.transFac = transFac;
+ config->codecSettings.bitRate = bitRate;
+ config->codecSettings.nChannels = numChannels;
+ config->codecSettings.sampleFreq = sampleRateCore;
+ config->codecSettings.transFac = transFac;
config->codecSettings.standardBitrate = standardBitrate;
if (bitRate < 28000) {
config->threshold_AmpRes_FF_m = (FIXP_DBL)MAXVAL_DBL;
config->threshold_AmpRes_FF_e = 7;
- }
- else if (bitRate >= 28000 && bitRate <= 48000) {
+ } else if (bitRate >= 28000 && bitRate <= 48000) {
/* The float threshold is 75
- 0.524288f is fractional part of RELAXATION, the quotaMatrix and therefore tonality are scaled by this
- 2/3 is because the original implementation divides the tonality values by 3, here it's divided by 2
- 128 compensates the necessary shiftfactor of 7 */
- config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(75.0f*0.524288f/(2.0f/3.0f)/128.0f);
+ 0.524288f is fractional part of RELAXATION, the quotaMatrix and therefore
+ tonality are scaled by this 2/3 is because the original implementation
+ divides the tonality values by 3, here it's divided by 2 128 compensates
+ the necessary shiftfactor of 7 */
+ config->threshold_AmpRes_FF_m =
+ FL2FXCONST_DBL(75.0f * 0.524288f / (2.0f / 3.0f) / 128.0f);
config->threshold_AmpRes_FF_e = 7;
- }
- else if (bitRate > 48000) {
+ } else if (bitRate > 48000) {
config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(0);
config->threshold_AmpRes_FF_e = 0;
}
- if (bitRate==0) {
+ if (bitRate == 0) {
/* map vbr quality to bitrate */
if (vbrMode < 30)
bitRate = 24000;
@@ -443,31 +488,29 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
bitRate = 48000;
bitRate *= numChannels;
/* fix to enable mono vbrMode<40 @ 44.1 of 48kHz */
- if (numChannels==1) {
- if (sampleRateSbr==44100 || sampleRateSbr==48000) {
- if (vbrMode<40) bitRate = 32000;
+ if (numChannels == 1) {
+ if (sampleRateSbr == 44100 || sampleRateSbr == 48000) {
+ if (vbrMode < 40) bitRate = 32000;
}
}
}
- idx = getSbrTuningTableIndex(bitRate,numChannels,sampleRateCore, core, NULL);
+ idx =
+ getSbrTuningTableIndex(bitRate, numChannels, sampleRateCore, core, NULL);
if (idx != INVALID_TABLE_IDX) {
- config->startFreq = sbrTuningTable[idx].startFreq ;
- config->stopFreq = sbrTuningTable[idx].stopFreq ;
+ config->startFreq = sbrTuningTable[idx].startFreq;
+ config->stopFreq = sbrTuningTable[idx].stopFreq;
if (useSpeechConfig) {
- config->startFreq = sbrTuningTable[idx].startFreqSpeech;
- config->stopFreq = sbrTuningTable[idx].stopFreqSpeech;
+ config->startFreq = sbrTuningTable[idx].startFreqSpeech;
+ config->stopFreq = sbrTuningTable[idx].stopFreqSpeech;
}
/* Adapt stop frequency in case of downsampled SBR - only 32 bands then */
if (1 == config->downSampleFactor) {
INT dsStopFreq = FDKsbrEnc_GetDownsampledStopFreq(
- sampleRateCore,
- config->startFreq,
- config->stopFreq,
- config->downSampleFactor
- );
+ sampleRateCore, config->startFreq, config->stopFreq,
+ config->downSampleFactor);
if (dsStopFreq < 0) {
return 0;
}
@@ -475,52 +518,68 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
config->stopFreq = dsStopFreq;
}
- config->sbr_noise_bands = sbrTuningTable[idx].numNoiseBands ;
- if (core == AOT_ER_AAC_ELD)
- config->init_amp_res_FF = SBR_AMP_RES_1_5;
- config->noiseFloorOffset= sbrTuningTable[idx].noiseFloorOffset;
+ config->sbr_noise_bands = sbrTuningTable[idx].numNoiseBands;
+ if (core == AOT_ER_AAC_ELD) config->init_amp_res_FF = SBR_AMP_RES_1_5;
+ config->noiseFloorOffset = sbrTuningTable[idx].noiseFloorOffset;
- config->ana_max_level = sbrTuningTable[idx].noiseMaxLevel ;
- config->stereoMode = sbrTuningTable[idx].stereoMode ;
- config->freqScale = sbrTuningTable[idx].freqScale ;
+ config->ana_max_level = sbrTuningTable[idx].noiseMaxLevel;
+ config->stereoMode = sbrTuningTable[idx].stereoMode;
+ config->freqScale = sbrTuningTable[idx].freqScale;
if (numChannels == 1) {
/* stereo case */
switch (core) {
case AOT_AAC_LC:
- if (bitRate <= (useSpeechConfig?24000U:20000U)) {
- config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
- config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
+ if (bitRate <= (useSpeechConfig ? 24000U : 20000U)) {
+ config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency
+ resolution for
+ non-split frames */
+ config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency
+ resolution for split
+ frames */
}
break;
case AOT_ER_AAC_ELD:
if (bitRate < 36000)
- config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
+ config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency
+ resolution for split
+ frames */
if (bitRate < 26000) {
- config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
- config->fResTransIsLow = 1; /* for transient frames, set low frequency resolution */
+ config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency
+ resolution for
+ non-split frames */
+ config->fResTransIsLow =
+ 1; /* for transient frames, set low frequency resolution */
}
break;
default:
break;
}
- }
- else {
+ } else {
/* stereo case */
switch (core) {
case AOT_AAC_LC:
if (bitRate <= 28000) {
- config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
- config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
+ config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency
+ resolution for
+ non-split frames */
+ config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency
+ resolution for split
+ frames */
}
break;
case AOT_ER_AAC_ELD:
if (bitRate < 72000) {
- config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
+ config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency
+ resolution for split
+ frames */
}
if (bitRate < 52000) {
- config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
- config->fResTransIsLow = 1; /* for transient frames, set low frequency resolution */
+ config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency
+ resolution for
+ non-split frames */
+ config->fResTransIsLow =
+ 1; /* for transient frames, set low frequency resolution */
}
break;
default:
@@ -535,24 +594,22 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
}
}
- /* adjust usage of parametric coding dependent on bitrate and speech config flag */
- if (useSpeechConfig)
- config->parametricCoding = 0;
+ /* adjust usage of parametric coding dependent on bitrate and speech config
+ * flag */
+ if (useSpeechConfig) config->parametricCoding = 0;
if (core == AOT_ER_AAC_ELD) {
- if (bitRate < 28000)
- config->init_amp_res_FF = SBR_AMP_RES_3_0;
+ if (bitRate < 28000) config->init_amp_res_FF = SBR_AMP_RES_3_0;
config->SendHeaderDataTime = -1;
}
if (numChannels == 1) {
if (bitRate < 16000) {
- config->parametricCoding = 0;
+ config->parametricCoding = 0;
}
- }
- else {
+ } else {
if (bitRate < 20000) {
- config->parametricCoding = 0;
+ config->parametricCoding = 0;
}
}
@@ -561,17 +618,16 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
/* PS settings */
config->bParametricStereo = bParametricStereo;
- return 1 ;
- }
- else {
- return 0 ;
+ return 1;
+ } else {
+ return 0;
}
}
/*****************************************************************************
functionname: FDKsbrEnc_InitializeSbrDefaults
- description: initializes the SBR confifuration
+ description: initializes the SBR configuration
returns: error status
input: - core codec type,
- factor of SBR to core frame length,
@@ -579,76 +635,73 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
output: initialized SBR configuration
*****************************************************************************/
-static UINT
-FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
- INT downSampleFactor,
- UINT codecGranuleLen
- ,const INT isLowDelay
- )
-{
- if ( (downSampleFactor < 1 || downSampleFactor > 2) ||
- (codecGranuleLen*downSampleFactor > QMF_CHANNELS*QMF_MAX_TIME_SLOTS) )
- return(0); /* error */
-
- config->SendHeaderDataTime = 1000;
- config->useWaveCoding = 0;
- config->crcSbr = 0;
- config->dynBwSupported = 1;
- if (isLowDelay)
- config->tran_thr = 6000;
- else
- config->tran_thr = 13000;
-
- config->parametricCoding = 1;
-
- config->sbrFrameSize = codecGranuleLen * downSampleFactor;
- config->downSampleFactor = downSampleFactor;
-
- /* sbr default parameters */
- config->sbr_data_extra = 0;
- config->amp_res = SBR_AMP_RES_3_0 ;
- config->tran_fc = 0 ;
- config->tran_det_mode = 1 ;
- config->spread = 1 ;
- config->stat = 0 ;
- config->e = 1 ;
- config->deltaTAcrossFrames = 1 ;
- config->dF_edge_1stEnv = FL2FXCONST_DBL(0.3f) ;
- config->dF_edge_incr = FL2FXCONST_DBL(0.3f) ;
-
- config->sbr_invf_mode = INVF_SWITCHED;
- config->sbr_xpos_mode = XPOS_LC;
- config->sbr_xpos_ctrl = SBR_XPOS_CTRL_DEFAULT;
- config->sbr_xpos_level = 0;
- config->useSaPan = 0;
- config->dynBwEnabled = 0;
-
-
- /* the following parameters are overwritten by the FDKsbrEnc_AdjustSbrSettings() function since
- they are included in the tuning table */
- config->stereoMode = SBR_SWITCH_LRC;
- config->ana_max_level = 6;
- config->noiseFloorOffset = 0;
- config->startFreq = 5; /* 5.9 respectively 6.0 kHz at fs = 44.1/48 kHz */
- config->stopFreq = 9; /* 16.2 respectively 16.8 kHz at fs = 44.1/48 kHz */
- config->freq_res_fixfix[0] = FREQ_RES_HIGH; /* non-split case */
- config->freq_res_fixfix[1] = FREQ_RES_HIGH; /* split case */
- config->fResTransIsLow = 0; /* for transient frames, set variable frequency resolution according to freqResTable */
-
- /* header_extra_1 */
- config->freqScale = SBR_FREQ_SCALE_DEFAULT;
- config->alterScale = SBR_ALTER_SCALE_DEFAULT;
- config->sbr_noise_bands = SBR_NOISE_BANDS_DEFAULT;
-
- /* header_extra_2 */
- config->sbr_limiter_bands = SBR_LIMITER_BANDS_DEFAULT;
- config->sbr_limiter_gains = SBR_LIMITER_GAINS_DEFAULT;
- config->sbr_interpol_freq = SBR_INTERPOL_FREQ_DEFAULT;
- config->sbr_smoothing_length = SBR_SMOOTHING_LENGTH_DEFAULT;
+static UINT FDKsbrEnc_InitializeSbrDefaults(sbrConfigurationPtr config,
+ INT downSampleFactor,
+ UINT codecGranuleLen,
+ const INT isLowDelay) {
+ if ((downSampleFactor < 1 || downSampleFactor > 2) ||
+ (codecGranuleLen * downSampleFactor > 64 * 32))
+ return (0); /* error */
+
+ config->SendHeaderDataTime = 1000;
+ config->useWaveCoding = 0;
+ config->crcSbr = 0;
+ config->dynBwSupported = 1;
+ if (isLowDelay)
+ config->tran_thr = 6000;
+ else
+ config->tran_thr = 13000;
+
+ config->parametricCoding = 1;
+
+ config->sbrFrameSize = codecGranuleLen * downSampleFactor;
+ config->downSampleFactor = downSampleFactor;
+
+ /* sbr default parameters */
+ config->sbr_data_extra = 0;
+ config->amp_res = SBR_AMP_RES_3_0;
+ config->tran_fc = 0;
+ config->tran_det_mode = 1;
+ config->spread = 1;
+ config->stat = 0;
+ config->e = 1;
+ config->deltaTAcrossFrames = 1;
+ config->dF_edge_1stEnv = FL2FXCONST_DBL(0.3f);
+ config->dF_edge_incr = FL2FXCONST_DBL(0.3f);
+
+ config->sbr_invf_mode = INVF_SWITCHED;
+ config->sbr_xpos_mode = XPOS_LC;
+ config->sbr_xpos_ctrl = SBR_XPOS_CTRL_DEFAULT;
+ config->sbr_xpos_level = 0;
+ config->useSaPan = 0;
+ config->dynBwEnabled = 0;
+
+ /* the following parameters are overwritten by the
+ FDKsbrEnc_AdjustSbrSettings() function since they are included in the
+ tuning table */
+ config->stereoMode = SBR_SWITCH_LRC;
+ config->ana_max_level = 6;
+ config->noiseFloorOffset = 0;
+ config->startFreq = 5; /* 5.9 respectively 6.0 kHz at fs = 44.1/48 kHz */
+ config->stopFreq = 9; /* 16.2 respectively 16.8 kHz at fs = 44.1/48 kHz */
+ config->freq_res_fixfix[0] = FREQ_RES_HIGH; /* non-split case */
+ config->freq_res_fixfix[1] = FREQ_RES_HIGH; /* split case */
+ config->fResTransIsLow = 0; /* for transient frames, set variable frequency
+ resolution according to freqResTable */
- return 1;
-}
+ /* header_extra_1 */
+ config->freqScale = SBR_FREQ_SCALE_DEFAULT;
+ config->alterScale = SBR_ALTER_SCALE_DEFAULT;
+ config->sbr_noise_bands = SBR_NOISE_BANDS_DEFAULT;
+ /* header_extra_2 */
+ config->sbr_limiter_bands = SBR_LIMITER_BANDS_DEFAULT;
+ config->sbr_limiter_gains = SBR_LIMITER_GAINS_DEFAULT;
+ config->sbr_interpol_freq = SBR_INTERPOL_FREQ_DEFAULT;
+ config->sbr_smoothing_length = SBR_SMOOTHING_LENGTH_DEFAULT;
+
+ return 1;
+}
/*****************************************************************************
@@ -659,19 +712,14 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
output: released handle
*****************************************************************************/
-static void
-deleteEnvChannel (HANDLE_ENV_CHANNEL hEnvCut)
-{
+static void deleteEnvChannel(HANDLE_ENV_CHANNEL hEnvCut) {
if (hEnvCut) {
-
FDKsbrEnc_DeleteTonCorrParamExtr(&hEnvCut->TonCorr);
- FDKsbrEnc_deleteExtractSbrEnvelope (&hEnvCut->sbrExtractEnvelope);
+ FDKsbrEnc_deleteExtractSbrEnvelope(&hEnvCut->sbrExtractEnvelope);
}
-
}
-
/*****************************************************************************
functionname: sbrEncoder_ChannelClose
@@ -681,12 +729,9 @@ deleteEnvChannel (HANDLE_ENV_CHANNEL hEnvCut)
output:
*****************************************************************************/
-static void
-sbrEncoder_ChannelClose(HANDLE_SBR_CHANNEL hSbrChannel)
-{
- if (hSbrChannel != NULL)
- {
- deleteEnvChannel (&hSbrChannel->hEnvChannel);
+static void sbrEncoder_ChannelClose(HANDLE_SBR_CHANNEL hSbrChannel) {
+ if (hSbrChannel != NULL) {
+ deleteEnvChannel(&hSbrChannel->hEnvChannel);
}
}
@@ -699,67 +744,60 @@ sbrEncoder_ChannelClose(HANDLE_SBR_CHANNEL hSbrChannel)
output:
*****************************************************************************/
-static void
-sbrEncoder_ElementClose(HANDLE_SBR_ELEMENT *phSbrElement)
-{
+static void sbrEncoder_ElementClose(HANDLE_SBR_ELEMENT *phSbrElement) {
HANDLE_SBR_ELEMENT hSbrElement = *phSbrElement;
- if (hSbrElement!=NULL) {
+ if (hSbrElement != NULL) {
if (hSbrElement->sbrConfigData.v_k_master)
FreeRam_Sbr_v_k_master(&hSbrElement->sbrConfigData.v_k_master);
if (hSbrElement->sbrConfigData.freqBandTable[LO])
- FreeRam_Sbr_freqBandTableLO(&hSbrElement->sbrConfigData.freqBandTable[LO]);
+ FreeRam_Sbr_freqBandTableLO(
+ &hSbrElement->sbrConfigData.freqBandTable[LO]);
if (hSbrElement->sbrConfigData.freqBandTable[HI])
- FreeRam_Sbr_freqBandTableHI(&hSbrElement->sbrConfigData.freqBandTable[HI]);
+ FreeRam_Sbr_freqBandTableHI(
+ &hSbrElement->sbrConfigData.freqBandTable[HI]);
FreeRam_SbrElement(phSbrElement);
}
- return ;
-
+ return;
}
-
-void sbrEncoder_Close (HANDLE_SBR_ENCODER *phSbrEncoder)
-{
+void sbrEncoder_Close(HANDLE_SBR_ENCODER *phSbrEncoder) {
HANDLE_SBR_ENCODER hSbrEncoder = *phSbrEncoder;
- if (hSbrEncoder != NULL)
- {
+ if (hSbrEncoder != NULL) {
int el, ch;
- for (el=0; el<(8); el++)
- {
- if (hSbrEncoder->sbrElement[el]!=NULL) {
+ for (el = 0; el < (8); el++) {
+ if (hSbrEncoder->sbrElement[el] != NULL) {
sbrEncoder_ElementClose(&hSbrEncoder->sbrElement[el]);
}
}
/* Close sbr Channels */
- for (ch=0; ch<(8); ch++)
- {
+ for (ch = 0; ch < (8); ch++) {
if (hSbrEncoder->pSbrChannel[ch]) {
sbrEncoder_ChannelClose(hSbrEncoder->pSbrChannel[ch]);
FreeRam_SbrChannel(&hSbrEncoder->pSbrChannel[ch]);
}
if (hSbrEncoder->QmfAnalysis[ch].FilterStates)
- FreeRam_Sbr_QmfStatesAnalysis((FIXP_QAS**)&hSbrEncoder->QmfAnalysis[ch].FilterStates);
-
-
+ FreeRam_Sbr_QmfStatesAnalysis(
+ (FIXP_QAS **)&hSbrEncoder->QmfAnalysis[ch].FilterStates);
}
if (hSbrEncoder->hParametricStereo)
PSEnc_Destroy(&hSbrEncoder->hParametricStereo);
if (hSbrEncoder->qmfSynthesisPS.FilterStates)
- FreeRam_PsQmfStatesSynthesis((FIXP_DBL**)&hSbrEncoder->qmfSynthesisPS.FilterStates);
+ FreeRam_PsQmfStatesSynthesis(
+ (FIXP_DBL **)&hSbrEncoder->qmfSynthesisPS.FilterStates);
/* Release Overlay */
- FreeRam_SbrDynamic_RAM((FIXP_DBL**)&hSbrEncoder->pSBRdynamic_RAM);
-
+ if (hSbrEncoder->pSBRdynamic_RAM)
+ FreeRam_SbrDynamic_RAM((FIXP_DBL **)&hSbrEncoder->pSBRdynamic_RAM);
FreeRam_SbrEncoder(phSbrEncoder);
}
-
}
/*****************************************************************************
@@ -771,67 +809,44 @@ void sbrEncoder_Close (HANDLE_SBR_ENCODER *phSbrEncoder)
output: error info
*****************************************************************************/
-static INT updateFreqBandTable(
- HANDLE_SBR_CONFIG_DATA sbrConfigData,
- HANDLE_SBR_HEADER_DATA sbrHeaderData,
- const INT downSampleFactor
- )
-{
+static INT updateFreqBandTable(HANDLE_SBR_CONFIG_DATA sbrConfigData,
+ HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ const INT downSampleFactor) {
INT k0, k2;
- if( FDKsbrEnc_FindStartAndStopBand (
- sbrConfigData->sampleFreq,
- sbrConfigData->sampleFreq >> (downSampleFactor-1),
- sbrConfigData->noQmfBands,
- sbrHeaderData->sbr_start_frequency,
- sbrHeaderData->sbr_stop_frequency,
- &k0,
- &k2
- )
- )
- return(1);
-
-
- if( FDKsbrEnc_UpdateFreqScale(
- sbrConfigData->v_k_master,
- &sbrConfigData->num_Master,
- k0,
- k2,
- sbrHeaderData->freqScale,
- sbrHeaderData->alterScale
- )
- )
- return(1);
-
-
- sbrHeaderData->sbr_xover_band=0;
-
-
- if( FDKsbrEnc_UpdateHiRes(
- sbrConfigData->freqBandTable[HI],
- &sbrConfigData->nSfb[HI],
- sbrConfigData->v_k_master,
- sbrConfigData->num_Master,
- &sbrHeaderData->sbr_xover_band
- )
- )
- return(1);
+ if (FDKsbrEnc_FindStartAndStopBand(
+ sbrConfigData->sampleFreq,
+ sbrConfigData->sampleFreq >> (downSampleFactor - 1),
+ sbrConfigData->noQmfBands, sbrHeaderData->sbr_start_frequency,
+ sbrHeaderData->sbr_stop_frequency, &k0, &k2))
+ return (1);
+ if (FDKsbrEnc_UpdateFreqScale(
+ sbrConfigData->v_k_master, &sbrConfigData->num_Master, k0, k2,
+ sbrHeaderData->freqScale, sbrHeaderData->alterScale))
+ return (1);
- FDKsbrEnc_UpdateLoRes(
- sbrConfigData->freqBandTable[LO],
- &sbrConfigData->nSfb[LO],
- sbrConfigData->freqBandTable[HI],
- sbrConfigData->nSfb[HI]
- );
+ sbrHeaderData->sbr_xover_band = 0;
+ if (FDKsbrEnc_UpdateHiRes(sbrConfigData->freqBandTable[HI],
+ &sbrConfigData->nSfb[HI], sbrConfigData->v_k_master,
+ sbrConfigData->num_Master,
+ &sbrHeaderData->sbr_xover_band))
+ return (1);
- sbrConfigData->xOverFreq = (sbrConfigData->freqBandTable[LOW_RES][0] * sbrConfigData->sampleFreq / sbrConfigData->noQmfBands+1)>>1;
+ FDKsbrEnc_UpdateLoRes(
+ sbrConfigData->freqBandTable[LO], &sbrConfigData->nSfb[LO],
+ sbrConfigData->freqBandTable[HI], sbrConfigData->nSfb[HI]);
+
+ sbrConfigData->xOverFreq =
+ (sbrConfigData->freqBandTable[LOW_RES][0] * sbrConfigData->sampleFreq /
+ sbrConfigData->noQmfBands +
+ 1) >>
+ 1;
return (0);
}
-
/*****************************************************************************
functionname: resetEnvChannel
@@ -841,27 +856,26 @@ static INT updateFreqBandTable(
output: hEnv
*****************************************************************************/
-static INT resetEnvChannel (HANDLE_SBR_CONFIG_DATA sbrConfigData,
- HANDLE_SBR_HEADER_DATA sbrHeaderData,
- HANDLE_ENV_CHANNEL hEnv)
-{
- /* note !!! hEnv->encEnvData.noOfnoisebands will be updated later in function FDKsbrEnc_extractSbrEnvelope !!!*/
- hEnv->TonCorr.sbrNoiseFloorEstimate.noiseBands = sbrHeaderData->sbr_noise_bands;
-
-
- if(FDKsbrEnc_ResetTonCorrParamExtr(&hEnv->TonCorr,
- sbrConfigData->xposCtrlSwitch,
- sbrConfigData->freqBandTable[HI][0],
- sbrConfigData->v_k_master,
- sbrConfigData->num_Master,
- sbrConfigData->sampleFreq,
- sbrConfigData->freqBandTable,
- sbrConfigData->nSfb,
- sbrConfigData->noQmfBands))
- return(1);
-
- hEnv->sbrCodeNoiseFloor.nSfb[LO] = hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
- hEnv->sbrCodeNoiseFloor.nSfb[HI] = hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
+static INT resetEnvChannel(HANDLE_SBR_CONFIG_DATA sbrConfigData,
+ HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_ENV_CHANNEL hEnv) {
+ /* note !!! hEnv->encEnvData.noOfnoisebands will be updated later in function
+ * FDKsbrEnc_extractSbrEnvelope !!!*/
+ hEnv->TonCorr.sbrNoiseFloorEstimate.noiseBands =
+ sbrHeaderData->sbr_noise_bands;
+
+ if (FDKsbrEnc_ResetTonCorrParamExtr(
+ &hEnv->TonCorr, sbrConfigData->xposCtrlSwitch,
+ sbrConfigData->freqBandTable[HI][0], sbrConfigData->v_k_master,
+ sbrConfigData->num_Master, sbrConfigData->sampleFreq,
+ sbrConfigData->freqBandTable, sbrConfigData->nSfb,
+ sbrConfigData->noQmfBands))
+ return (1);
+
+ hEnv->sbrCodeNoiseFloor.nSfb[LO] =
+ hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
+ hEnv->sbrCodeNoiseFloor.nSfb[HI] =
+ hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
hEnv->sbrCodeEnvelope.nSfb[LO] = sbrConfigData->nSfb[LO];
hEnv->sbrCodeEnvelope.nSfb[HI] = sbrConfigData->nSfb[HI];
@@ -874,16 +888,17 @@ static INT resetEnvChannel (HANDLE_SBR_CONFIG_DATA sbrConfigData,
return (0);
}
-/* ****************************** FDKsbrEnc_SbrGetXOverFreq ******************************/
+/* ****************************** FDKsbrEnc_SbrGetXOverFreq
+ * ******************************/
/**
* @fn
* @brief calculates the closest possible crossover frequency
* @return the crossover frequency SBR accepts
*
*/
-static INT
-FDKsbrEnc_SbrGetXOverFreq(HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR encoder instance */
- INT xoverFreq) /*!< from core coder suggested crossover frequency */
+static INT FDKsbrEnc_SbrGetXOverFreq(
+ HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR encoder instance */
+ INT xoverFreq) /*!< from core coder suggested crossover frequency */
{
INT band;
INT lastDiff, newDiff;
@@ -892,13 +907,15 @@ FDKsbrEnc_SbrGetXOverFreq(HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR en
UCHAR *RESTRICT pVKMaster = hEnv->sbrConfigData.v_k_master;
/* Check if there is a matching cutoff frequency in the master table */
- cutoffSb = (4*xoverFreq * hEnv->sbrConfigData.noQmfBands / hEnv->sbrConfigData.sampleFreq + 1)>>1;
+ cutoffSb = (4 * xoverFreq * hEnv->sbrConfigData.noQmfBands /
+ hEnv->sbrConfigData.sampleFreq +
+ 1) >>
+ 1;
lastDiff = cutoffSb;
for (band = 0; band < hEnv->sbrConfigData.num_Master; band++) {
-
newDiff = fixp_abs((INT)pVKMaster[band] - cutoffSb);
- if(newDiff >= lastDiff) {
+ if (newDiff >= lastDiff) {
band--;
break;
}
@@ -906,7 +923,10 @@ FDKsbrEnc_SbrGetXOverFreq(HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR en
lastDiff = newDiff;
}
- return ((pVKMaster[band] * hEnv->sbrConfigData.sampleFreq/hEnv->sbrConfigData.noQmfBands+1)>>1);
+ return ((pVKMaster[band] * hEnv->sbrConfigData.sampleFreq /
+ hEnv->sbrConfigData.noQmfBands +
+ 1) >>
+ 1);
}
/*****************************************************************************
@@ -918,32 +938,27 @@ FDKsbrEnc_SbrGetXOverFreq(HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR en
output:
*****************************************************************************/
-INT
-FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
- int iElement,
- INT_PCM *samples, /*!< time samples, always interleaved */
- UINT timeInStride, /*!< time buffer channel interleaving stride */
- UINT *sbrDataBits, /*!< Size of SBR payload */
- UCHAR *sbrData, /*!< SBR payload */
- int clearOutput /*!< Do not consider any input signal */
- )
-{
+INT FDKsbrEnc_EnvEncodeFrame(
+ HANDLE_SBR_ENCODER hEnvEncoder, int iElement,
+ INT_PCM *samples, /*!< time samples, always deinterleaved */
+ UINT samplesBufSize, /*!< time buffer channel stride */
+ UINT *sbrDataBits, /*!< Size of SBR payload */
+ UCHAR *sbrData, /*!< SBR payload */
+ int clearOutput /*!< Do not consider any input signal */
+) {
HANDLE_SBR_ELEMENT hSbrElement = NULL;
- FDK_CRCINFO crcInfo;
- INT crcReg;
- INT ch;
- INT band;
- INT cutoffSb;
- INT newXOver;
-
- if (hEnvEncoder == NULL)
- return -1;
+ FDK_CRCINFO crcInfo;
+ INT crcReg;
+ INT ch;
+ INT band;
+ INT cutoffSb;
+ INT newXOver;
- hSbrElement = hEnvEncoder->sbrElement[iElement];
+ if (hEnvEncoder == NULL) return -1;
- if (hSbrElement == NULL)
- return -1;
+ hSbrElement = hEnvEncoder->sbrElement[iElement];
+ if (hSbrElement == NULL) return -1;
/* header bitstream handling */
HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData = &hSbrElement->sbrBitstreamData;
@@ -951,33 +966,33 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
INT psHeaderActive = 0;
sbrBitstreamData->HeaderActive = 0;
- /* Anticipate PS header because of internal PS bitstream delay in order to be in sync with SBR header. */
- if ( sbrBitstreamData->CountSendHeaderData==(sbrBitstreamData->NrSendHeaderData-1) )
- {
- psHeaderActive = 1;
+ /* Anticipate PS header because of internal PS bitstream delay in order to be
+ * in sync with SBR header. */
+ if (sbrBitstreamData->CountSendHeaderData ==
+ (sbrBitstreamData->NrSendHeaderData - 1)) {
+ psHeaderActive = 1;
}
/* Signal SBR header to be written into bitstream */
- if ( sbrBitstreamData->CountSendHeaderData==0 )
- {
- sbrBitstreamData->HeaderActive = 1;
+ if (sbrBitstreamData->CountSendHeaderData == 0) {
+ sbrBitstreamData->HeaderActive = 1;
}
/* Increment header interval counter */
if (sbrBitstreamData->NrSendHeaderData == 0) {
sbrBitstreamData->CountSendHeaderData = 1;
- }
- else {
+ } else {
if (sbrBitstreamData->CountSendHeaderData >= 0) {
sbrBitstreamData->CountSendHeaderData++;
- sbrBitstreamData->CountSendHeaderData %= sbrBitstreamData->NrSendHeaderData;
+ sbrBitstreamData->CountSendHeaderData %=
+ sbrBitstreamData->NrSendHeaderData;
}
}
- if (hSbrElement->CmonData.dynBwEnabled ) {
+ if (hSbrElement->CmonData.dynBwEnabled) {
INT i;
- for ( i = 4; i > 0; i-- )
- hSbrElement->dynXOverFreqDelay[i] = hSbrElement->dynXOverFreqDelay[i-1];
+ for (i = 4; i > 0; i--)
+ hSbrElement->dynXOverFreqDelay[i] = hSbrElement->dynXOverFreqDelay[i - 1];
hSbrElement->dynXOverFreqDelay[0] = hSbrElement->CmonData.dynXOverFreqEnc;
if (hSbrElement->dynXOverFreqDelay[1] > hSbrElement->dynXOverFreqDelay[2])
@@ -986,41 +1001,38 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
newXOver = hSbrElement->dynXOverFreqDelay[1];
/* has the crossover frequency changed? */
- if ( hSbrElement->sbrConfigData.dynXOverFreq != newXOver ) {
-
+ if (hSbrElement->sbrConfigData.dynXOverFreq != newXOver) {
/* get corresponding master band */
- cutoffSb = ((4* newXOver * hSbrElement->sbrConfigData.noQmfBands
- / hSbrElement->sbrConfigData.sampleFreq)+1)>>1;
+ cutoffSb = ((4 * newXOver * hSbrElement->sbrConfigData.noQmfBands /
+ hSbrElement->sbrConfigData.sampleFreq) +
+ 1) >>
+ 1;
- for ( band = 0; band < hSbrElement->sbrConfigData.num_Master; band++ ) {
- if ( cutoffSb == hSbrElement->sbrConfigData.v_k_master[band] )
- break;
+ for (band = 0; band < hSbrElement->sbrConfigData.num_Master; band++) {
+ if (cutoffSb == hSbrElement->sbrConfigData.v_k_master[band]) break;
}
- FDK_ASSERT( band < hSbrElement->sbrConfigData.num_Master );
+ FDK_ASSERT(band < hSbrElement->sbrConfigData.num_Master);
hSbrElement->sbrConfigData.dynXOverFreq = newXOver;
hSbrElement->sbrHeaderData.sbr_xover_band = band;
- hSbrElement->sbrBitstreamData.HeaderActive=1;
+ hSbrElement->sbrBitstreamData.HeaderActive = 1;
psHeaderActive = 1; /* ps header is one frame delayed */
/*
update vk_master table
*/
- if(updateFreqBandTable(&hSbrElement->sbrConfigData,
- &hSbrElement->sbrHeaderData,
- hEnvEncoder->downSampleFactor
- ))
- return(1);
-
+ if (updateFreqBandTable(&hSbrElement->sbrConfigData,
+ &hSbrElement->sbrHeaderData,
+ hEnvEncoder->downSampleFactor))
+ return (1);
/* reset SBR channels */
INT nEnvCh = hSbrElement->sbrConfigData.nChannels;
- for ( ch = 0; ch < nEnvCh; ch++ ) {
- if(resetEnvChannel (&hSbrElement->sbrConfigData,
+ for (ch = 0; ch < nEnvCh; ch++) {
+ if (resetEnvChannel(&hSbrElement->sbrConfigData,
&hSbrElement->sbrHeaderData,
&hSbrElement->sbrChannel[ch]->hEnvChannel))
- return(1);
-
+ return (1);
}
}
}
@@ -1028,11 +1040,11 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
/*
allocate space for dummy header and crc
*/
- crcReg = FDKsbrEnc_InitSbrBitstream(&hSbrElement->CmonData,
- hSbrElement->payloadDelayLine[hEnvEncoder->nBitstrDelay],
- MAX_PAYLOAD_SIZE*sizeof(UCHAR),
- &crcInfo,
- hSbrElement->sbrConfigData.sbrSyntaxFlags);
+ crcReg = FDKsbrEnc_InitSbrBitstream(
+ &hSbrElement->CmonData,
+ hSbrElement->payloadDelayLine[hEnvEncoder->nBitstrDelay],
+ MAX_PAYLOAD_SIZE * sizeof(UCHAR), &crcInfo,
+ hSbrElement->sbrConfigData.sbrSyntaxFlags);
/* Temporal Envelope Data */
SBR_FRAME_TEMP_DATA _fData;
@@ -1047,61 +1059,47 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
FDKmemclear(&eData[1], sizeof(SBR_ENV_TEMP_DATA));
FDKmemclear(fData, sizeof(SBR_FRAME_TEMP_DATA));
- for(i=0; i<MAX_NUM_NOISE_VALUES; i++)
- fData->res[i] = FREQ_RES_HIGH;
+ for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) fData->res[i] = FREQ_RES_HIGH;
}
-
- if (!clearOutput)
- {
+ if (!clearOutput) {
/*
* Transform audio data into QMF domain
*/
- for(ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++)
- {
+ for (ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++) {
HANDLE_ENV_CHANNEL h_envChan = &hSbrElement->sbrChannel[ch]->hEnvChannel;
HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &h_envChan->sbrExtractEnvelope;
- if(hSbrElement->elInfo.fParametricStereo == 0)
- {
+ if (hSbrElement->elInfo.fParametricStereo == 0) {
QMF_SCALE_FACTOR tmpScale;
FIXP_DBL **pQmfReal, **pQmfImag;
- C_AALLOC_SCRATCH_START(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2)
-
+ C_AALLOC_SCRATCH_START(qmfWorkBuffer, FIXP_DBL, 64 * 2)
/* Obtain pointers to QMF buffers. */
pQmfReal = sbrExtrEnv->rBuffer;
pQmfImag = sbrExtrEnv->iBuffer;
- qmfAnalysisFiltering( hSbrElement->hQmfAnalysis[ch],
- pQmfReal,
- pQmfImag,
- &tmpScale,
- samples + hSbrElement->elInfo.ChannelIndex[ch],
- timeInStride,
- qmfWorkBuffer );
+ qmfAnalysisFiltering(
+ hSbrElement->hQmfAnalysis[ch], pQmfReal, pQmfImag, &tmpScale,
+ samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize, 0,
+ 1, qmfWorkBuffer);
h_envChan->qmfScale = tmpScale.lb_scale + 7;
-
- C_AALLOC_SCRATCH_END(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2)
+ C_AALLOC_SCRATCH_END(qmfWorkBuffer, FIXP_DBL, 64 * 2)
} /* fParametricStereo == 0 */
-
/*
Parametric Stereo processing
*/
- if (hSbrElement->elInfo.fParametricStereo)
- {
+ if (hSbrElement->elInfo.fParametricStereo) {
INT error = noError;
-
/* Limit Parametric Stereo to one instance */
FDK_ASSERT(ch == 0);
-
- if(error == noError){
+ if (error == noError) {
/* parametric stereo processing:
- input:
o left and right time domain samples
@@ -1111,28 +1109,22 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
o ps parameter extraction
o downmix + hybrid synthesis
- output:
- o downmixed qmf data is written to sbrExtrEnv->rBuffer and sbrExtrEnv->iBuffer
+ o downmixed qmf data is written to sbrExtrEnv->rBuffer and
+ sbrExtrEnv->iBuffer
*/
SCHAR qmfScale;
- INT_PCM* pSamples[2] = {samples + hSbrElement->elInfo.ChannelIndex[0],samples + hSbrElement->elInfo.ChannelIndex[1]};
- error = FDKsbrEnc_PSEnc_ParametricStereoProcessing( hEnvEncoder->hParametricStereo,
- pSamples,
- timeInStride,
- hSbrElement->hQmfAnalysis,
- sbrExtrEnv->rBuffer,
- sbrExtrEnv->iBuffer,
- samples + hSbrElement->elInfo.ChannelIndex[ch],
- &hEnvEncoder->qmfSynthesisPS,
- &qmfScale,
- psHeaderActive );
- if (noError != error)
- {
- error = handBack(error);
- }
+ INT_PCM *pSamples[2] = {
+ samples + hSbrElement->elInfo.ChannelIndex[0] * samplesBufSize,
+ samples + hSbrElement->elInfo.ChannelIndex[1] * samplesBufSize};
+ error = FDKsbrEnc_PSEnc_ParametricStereoProcessing(
+ hEnvEncoder->hParametricStereo, pSamples, samplesBufSize,
+ hSbrElement->hQmfAnalysis, sbrExtrEnv->rBuffer,
+ sbrExtrEnv->iBuffer,
+ samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize,
+ &hEnvEncoder->qmfSynthesisPS, &qmfScale, psHeaderActive);
h_envChan->qmfScale = (int)qmfScale;
}
-
} /* if (hEnvEncoder->hParametricStereo) */
/*
@@ -1140,80 +1132,146 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
Extract Envelope relevant things from QMF data
*/
- FDKsbrEnc_extractSbrEnvelope1(
- &hSbrElement->sbrConfigData,
- &hSbrElement->sbrHeaderData,
- &hSbrElement->sbrBitstreamData,
- h_envChan,
- &hSbrElement->CmonData,
- &eData[ch],
- fData
- );
+ FDKsbrEnc_extractSbrEnvelope1(&hSbrElement->sbrConfigData,
+ &hSbrElement->sbrHeaderData,
+ &hSbrElement->sbrBitstreamData, h_envChan,
+ &hSbrElement->CmonData, &eData[ch], fData);
} /* hEnvEncoder->sbrConfigData.nChannels */
- }
+ }
/*
- Process Envelope relevant things and calculate envelope data and write payload
+ Process Envelope relevant things and calculate envelope data and write
+ payload
*/
FDKsbrEnc_extractSbrEnvelope2(
- &hSbrElement->sbrConfigData,
- &hSbrElement->sbrHeaderData,
- (hSbrElement->elInfo.fParametricStereo) ? hEnvEncoder->hParametricStereo : NULL,
- &hSbrElement->sbrBitstreamData,
- &hSbrElement->sbrChannel[0]->hEnvChannel,
- &hSbrElement->sbrChannel[1]->hEnvChannel,
- &hSbrElement->CmonData,
- eData,
- fData,
- clearOutput
- );
+ &hSbrElement->sbrConfigData, &hSbrElement->sbrHeaderData,
+ (hSbrElement->elInfo.fParametricStereo) ? hEnvEncoder->hParametricStereo
+ : NULL,
+ &hSbrElement->sbrBitstreamData, &hSbrElement->sbrChannel[0]->hEnvChannel,
+ (hSbrElement->sbrConfigData.stereoMode != SBR_MONO)
+ ? &hSbrElement->sbrChannel[1]->hEnvChannel
+ : NULL,
+ &hSbrElement->CmonData, eData, fData, clearOutput);
+
+ hSbrElement->sbrBitstreamData.rightBorderFIX = 0;
/*
format payload, calculate crc
*/
- FDKsbrEnc_AssembleSbrBitstream(&hSbrElement->CmonData, &crcInfo, crcReg, hSbrElement->sbrConfigData.sbrSyntaxFlags);
+ FDKsbrEnc_AssembleSbrBitstream(&hSbrElement->CmonData, &crcInfo, crcReg,
+ hSbrElement->sbrConfigData.sbrSyntaxFlags);
/*
save new payload, set to zero length if greater than MAX_PAYLOAD_SIZE
*/
- hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] = FDKgetValidBits(&hSbrElement->CmonData.sbrBitbuf);
+ hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] =
+ FDKgetValidBits(&hSbrElement->CmonData.sbrBitbuf);
- if(hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] > (MAX_PAYLOAD_SIZE<<3))
- hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay]=0;
+ if (hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] >
+ (MAX_PAYLOAD_SIZE << 3))
+ hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] = 0;
/* While filling the Delay lines, sbrData is NULL */
if (sbrData) {
*sbrDataBits = hSbrElement->payloadDelayLineSize[0];
- FDKmemcpy(sbrData, hSbrElement->payloadDelayLine[0], (hSbrElement->payloadDelayLineSize[0]+7)>>3);
-
+ FDKmemcpy(sbrData, hSbrElement->payloadDelayLine[0],
+ (hSbrElement->payloadDelayLineSize[0] + 7) >> 3);
+ }
+ /* delay header active flag */
+ if (hSbrElement->sbrBitstreamData.HeaderActive == 1) {
+ hSbrElement->sbrBitstreamData.HeaderActiveDelay =
+ 1 + hEnvEncoder->nBitstrDelay;
+ } else {
+ if (hSbrElement->sbrBitstreamData.HeaderActiveDelay > 0) {
+ hSbrElement->sbrBitstreamData.HeaderActiveDelay--;
+ }
}
+ return (0);
+}
-/*******************************/
+/*****************************************************************************
- if (hEnvEncoder->fTimeDomainDownsampling)
- {
- int ch;
- int nChannels = hSbrElement->sbrConfigData.nChannels;
+ functionname: FDKsbrEnc_Downsample
+ description: performs downsampling and delay compensation of the core path
+ returns:
+ input:
+ output:
- for (ch=0; ch < nChannels; ch++)
- {
- INT nOutSamples;
-
- FDKaacEnc_Downsample(&hSbrElement->sbrChannel[ch]->downSampler,
- samples + hSbrElement->elInfo.ChannelIndex[ch] + hEnvEncoder->bufferOffset,
- hSbrElement->sbrConfigData.frameSize,
- timeInStride,
- samples + hSbrElement->elInfo.ChannelIndex[ch],
- &nOutSamples,
- hEnvEncoder->nChannels);
+*****************************************************************************/
+INT FDKsbrEnc_Downsample(
+ HANDLE_SBR_ENCODER hSbrEncoder,
+ INT_PCM *samples, /*!< time samples, always deinterleaved */
+ UINT samplesBufSize, /*!< time buffer size per channel */
+ UINT numChannels, /*!< number of channels */
+ UINT *sbrDataBits, /*!< Size of SBR payload */
+ UCHAR *sbrData, /*!< SBR payload */
+ int clearOutput /*!< Do not consider any input signal */
+) {
+ HANDLE_SBR_ELEMENT hSbrElement = NULL;
+ INT nOutSamples;
+ int el;
+ if (hSbrEncoder->downSampleFactor > 1) {
+ /* Do downsampling */
+
+ /* Loop over elements (LFE is handled later) */
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ hSbrElement = hSbrEncoder->sbrElement[el];
+ if (hSbrEncoder->sbrElement[el] != NULL) {
+ if (hSbrEncoder->downsamplingMethod == SBRENC_DS_TIME) {
+ int ch;
+ int nChannels = hSbrElement->sbrConfigData.nChannels;
+
+ for (ch = 0; ch < nChannels; ch++) {
+ FDKaacEnc_Downsample(
+ &hSbrElement->sbrChannel[ch]->downSampler,
+ samples +
+ hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize +
+ hSbrEncoder->bufferOffset / numChannels,
+ hSbrElement->sbrConfigData.frameSize,
+ samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize,
+ &nOutSamples);
+ }
+ }
+ }
}
- } /* downsample */
+ /* Handle LFE (if existing) */
+ if (hSbrEncoder->lfeChIdx != -1) { /* lfe downsampler */
+ FDKaacEnc_Downsample(&hSbrEncoder->lfeDownSampler,
+ samples + hSbrEncoder->lfeChIdx * samplesBufSize +
+ hSbrEncoder->bufferOffset / numChannels,
+ hSbrEncoder->frameSize,
+ samples + hSbrEncoder->lfeChIdx * samplesBufSize,
+ &nOutSamples);
+ }
+ } else {
+ /* No downsampling. Still, some buffer shifting for correct delay */
+ int samples2Copy = hSbrEncoder->frameSize;
+ if (hSbrEncoder->bufferOffset / (int)numChannels < samples2Copy) {
+ for (int c = 0; c < (int)numChannels; c++) {
+ /* Do memmove while taking care of overlapping memory areas. (memcpy
+ does not necessarily take care) Distinguish between oeverlapping and
+ non overlapping version due to reasons of complexity. */
+ FDKmemmove(samples + c * samplesBufSize,
+ samples + c * samplesBufSize +
+ hSbrEncoder->bufferOffset / numChannels,
+ samples2Copy * sizeof(INT_PCM));
+ }
+ } else {
+ for (int c = 0; c < (int)numChannels; c++) {
+ /* Simple memcpy since the memory areas are not overlapping */
+ FDKmemcpy(samples + c * samplesBufSize,
+ samples + c * samplesBufSize +
+ hSbrEncoder->bufferOffset / numChannels,
+ samples2Copy * sizeof(INT_PCM));
+ }
+ }
+ }
- return (0);
+ return 0;
}
/*****************************************************************************
@@ -1226,27 +1284,17 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
*****************************************************************************/
-static INT
-createEnvChannel (HANDLE_ENV_CHANNEL hEnv,
- INT channel
- ,UCHAR* dynamic_RAM
- )
-{
- FDKmemclear(hEnv,sizeof (struct ENV_CHANNEL));
+static INT createEnvChannel(HANDLE_ENV_CHANNEL hEnv, INT channel,
+ UCHAR *dynamic_RAM) {
+ FDKmemclear(hEnv, sizeof(struct ENV_CHANNEL));
- if ( FDKsbrEnc_CreateTonCorrParamExtr(&hEnv->TonCorr,
- channel) )
- {
- return(1);
+ if (FDKsbrEnc_CreateTonCorrParamExtr(&hEnv->TonCorr, channel)) {
+ return (1);
}
- if ( FDKsbrEnc_CreateExtractSbrEnvelope (&hEnv->sbrExtractEnvelope,
- channel
- ,/*chan*/0
- ,dynamic_RAM
- ) )
- {
- return(1);
+ if (FDKsbrEnc_CreateExtractSbrEnvelope(&hEnv->sbrExtractEnvelope, channel,
+ /*chan*/ 0, dynamic_RAM)) {
+ return (1);
}
return 0;
@@ -1261,21 +1309,16 @@ createEnvChannel (HANDLE_ENV_CHANNEL hEnv,
output:
*****************************************************************************/
-static INT
-initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
- HANDLE_SBR_HEADER_DATA sbrHeaderData,
- HANDLE_ENV_CHANNEL hEnv,
- sbrConfigurationPtr params,
- ULONG statesInitFlag
- ,INT chanInEl
- ,UCHAR* dynamic_RAM
- )
-{
- int frameShift, tran_off=0;
+static INT initEnvChannel(HANDLE_SBR_CONFIG_DATA sbrConfigData,
+ HANDLE_SBR_HEADER_DATA sbrHeaderData,
+ HANDLE_ENV_CHANNEL hEnv, sbrConfigurationPtr params,
+ ULONG statesInitFlag, INT chanInEl,
+ UCHAR *dynamic_RAM) {
+ int frameShift, tran_off = 0;
INT e;
INT tran_fc;
INT timeSlots, timeStep, startIndex;
- INT noiseBands[2] = { 3, 3 };
+ INT noiseBands[2] = {3, 3};
e = 1 << params->e;
@@ -1283,11 +1326,12 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
hEnv->encEnvData.freq_res_fixfix[0] = params->freq_res_fixfix[0];
hEnv->encEnvData.freq_res_fixfix[1] = params->freq_res_fixfix[1];
- hEnv->encEnvData.fResTransIsLow = params->fResTransIsLow;
+ hEnv->encEnvData.fResTransIsLow = params->fResTransIsLow;
hEnv->fLevelProtect = 0;
- hEnv->encEnvData.ldGrid = (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? 1 : 0;
+ hEnv->encEnvData.ldGrid =
+ (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? 1 : 0;
hEnv->encEnvData.sbr_xpos_mode = (XPOS_MODE)params->sbr_xpos_mode;
@@ -1298,19 +1342,16 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
*/
sbrConfigData->switchTransposers = TRUE;
hEnv->encEnvData.sbr_xpos_mode = XPOS_MDCT;
- }
- else {
+ } else {
sbrConfigData->switchTransposers = FALSE;
}
hEnv->encEnvData.sbr_xpos_ctrl = params->sbr_xpos_ctrl;
-
/* extended data */
- if(params->parametricCoding) {
+ if (params->parametricCoding) {
hEnv->encEnvData.extended_data = 1;
- }
- else {
+ } else {
hEnv->encEnvData.extended_data = 0;
}
@@ -1319,40 +1360,37 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
startIndex = QMF_FILTER_PROTOTYPE_SIZE - sbrConfigData->noQmfBands;
switch (params->sbrFrameSize) {
- case 2304:
- timeSlots = 18;
- break;
- case 2048:
- case 1024:
- case 512:
- timeSlots = 16;
- break;
- case 1920:
- case 960:
- case 480:
- timeSlots = 15;
- break;
- case 1152:
- timeSlots = 9;
- break;
- default:
- return (1); /* Illegal frame size */
+ case 2304:
+ timeSlots = 18;
+ break;
+ case 2048:
+ case 1024:
+ case 512:
+ timeSlots = 16;
+ break;
+ case 1920:
+ case 960:
+ case 480:
+ timeSlots = 15;
+ break;
+ case 1152:
+ timeSlots = 9;
+ break;
+ default:
+ return (1); /* Illegal frame size */
}
timeStep = sbrConfigData->noQmfSlots / timeSlots;
- if ( FDKsbrEnc_InitTonCorrParamExtr(params->sbrFrameSize,
- &hEnv->TonCorr,
- sbrConfigData,
- timeSlots,
- params->sbr_xpos_ctrl,
- params->ana_max_level,
- sbrHeaderData->sbr_noise_bands,
- params->noiseFloorOffset,
- params->useSpeechConfig) )
- return(1);
+ if (FDKsbrEnc_InitTonCorrParamExtr(
+ params->sbrFrameSize, &hEnv->TonCorr, sbrConfigData, timeSlots,
+ params->sbr_xpos_ctrl, params->ana_max_level,
+ sbrHeaderData->sbr_noise_bands, params->noiseFloorOffset,
+ params->useSpeechConfig))
+ return (1);
- hEnv->encEnvData.noOfnoisebands = hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
+ hEnv->encEnvData.noOfnoisebands =
+ hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
noiseBands[0] = hEnv->encEnvData.noOfnoisebands;
noiseBands[1] = hEnv->encEnvData.noOfnoisebands;
@@ -1362,106 +1400,90 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
if (hEnv->encEnvData.sbr_invf_mode == INVF_SWITCHED) {
hEnv->encEnvData.sbr_invf_mode = INVF_MID_LEVEL;
hEnv->TonCorr.switchInverseFilt = TRUE;
- }
- else {
+ } else {
hEnv->TonCorr.switchInverseFilt = FALSE;
}
-
- tran_fc = params->tran_fc;
+ tran_fc = params->tran_fc;
if (tran_fc == 0) {
- tran_fc = fixMin (5000, FDKsbrEnc_getSbrStartFreqRAW (sbrHeaderData->sbr_start_frequency,params->codecSettings.sampleFreq));
+ tran_fc = fixMin(
+ 5000, FDKsbrEnc_getSbrStartFreqRAW(sbrHeaderData->sbr_start_frequency,
+ params->codecSettings.sampleFreq));
}
- tran_fc = (tran_fc*4*sbrConfigData->noQmfBands/sbrConfigData->sampleFreq + 1)>>1;
+ tran_fc =
+ (tran_fc * 4 * sbrConfigData->noQmfBands / sbrConfigData->sampleFreq +
+ 1) >>
+ 1;
if (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
frameShift = LD_PRETRAN_OFF;
- tran_off = LD_PRETRAN_OFF + FRAME_MIDDLE_SLOT_512LD*timeStep;
- } else
- {
+ tran_off = LD_PRETRAN_OFF + FRAME_MIDDLE_SLOT_512LD * timeStep;
+ } else {
frameShift = 0;
switch (timeSlots) {
/* The factor of 2 is by definition. */
- case NUMBER_TIME_SLOTS_2048: tran_off = 8 + FRAME_MIDDLE_SLOT_2048 * timeStep; break;
- case NUMBER_TIME_SLOTS_1920: tran_off = 7 + FRAME_MIDDLE_SLOT_1920 * timeStep; break;
- default: return 1;
+ case NUMBER_TIME_SLOTS_2048:
+ tran_off = 8 + FRAME_MIDDLE_SLOT_2048 * timeStep;
+ break;
+ case NUMBER_TIME_SLOTS_1920:
+ tran_off = 7 + FRAME_MIDDLE_SLOT_1920 * timeStep;
+ break;
+ default:
+ return 1;
}
}
- if ( FDKsbrEnc_InitExtractSbrEnvelope (&hEnv->sbrExtractEnvelope,
- sbrConfigData->noQmfSlots,
- sbrConfigData->noQmfBands, startIndex,
- timeSlots, timeStep, tran_off,
- statesInitFlag
- ,chanInEl
- ,dynamic_RAM
- ,sbrConfigData->sbrSyntaxFlags
- ) )
- return(1);
-
- if(FDKsbrEnc_InitSbrCodeEnvelope (&hEnv->sbrCodeEnvelope,
- sbrConfigData->nSfb,
- params->deltaTAcrossFrames,
- params->dF_edge_1stEnv,
- params->dF_edge_incr))
- return(1);
-
- if(FDKsbrEnc_InitSbrCodeEnvelope (&hEnv->sbrCodeNoiseFloor,
- noiseBands,
- params->deltaTAcrossFrames,
- 0,0))
- return(1);
+ if (FDKsbrEnc_InitExtractSbrEnvelope(
+ &hEnv->sbrExtractEnvelope, sbrConfigData->noQmfSlots,
+ sbrConfigData->noQmfBands, startIndex, timeSlots, timeStep, tran_off,
+ statesInitFlag, chanInEl, dynamic_RAM, sbrConfigData->sbrSyntaxFlags))
+ return (1);
+
+ if (FDKsbrEnc_InitSbrCodeEnvelope(&hEnv->sbrCodeEnvelope, sbrConfigData->nSfb,
+ params->deltaTAcrossFrames,
+ params->dF_edge_1stEnv,
+ params->dF_edge_incr))
+ return (1);
+
+ if (FDKsbrEnc_InitSbrCodeEnvelope(&hEnv->sbrCodeNoiseFloor, noiseBands,
+ params->deltaTAcrossFrames, 0, 0))
+ return (1);
sbrConfigData->initAmpResFF = params->init_amp_res_FF;
- if(FDKsbrEnc_InitSbrHuffmanTables (&hEnv->encEnvData,
- &hEnv->sbrCodeEnvelope,
- &hEnv->sbrCodeNoiseFloor,
- sbrHeaderData->sbr_amp_res))
- return(1);
-
- FDKsbrEnc_initFrameInfoGenerator (&hEnv->SbrEnvFrame,
- params->spread,
- e,
- params->stat,
- timeSlots,
- hEnv->encEnvData.freq_res_fixfix,
- hEnv->encEnvData.fResTransIsLow,
- hEnv->encEnvData.ldGrid
- );
-
- if(sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
+ if (FDKsbrEnc_InitSbrHuffmanTables(&hEnv->encEnvData, &hEnv->sbrCodeEnvelope,
+ &hEnv->sbrCodeNoiseFloor,
+ sbrHeaderData->sbr_amp_res))
+ return (1);
+
+ FDKsbrEnc_initFrameInfoGenerator(
+ &hEnv->SbrEnvFrame, params->spread, e, params->stat, timeSlots,
+ hEnv->encEnvData.freq_res_fixfix, hEnv->encEnvData.fResTransIsLow,
+ hEnv->encEnvData.ldGrid);
+
+ if (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
+
{
- INT bandwidth_qmf_slot = (sbrConfigData->sampleFreq>>1) / (sbrConfigData->noQmfBands);
- if(FDKsbrEnc_InitSbrFastTransientDetector(
- &hEnv->sbrFastTransientDetector,
- sbrConfigData->noQmfSlots,
- bandwidth_qmf_slot,
- sbrConfigData->noQmfBands,
- sbrConfigData->freqBandTable[0][0]
- ))
- return(1);
+ INT bandwidth_qmf_slot =
+ (sbrConfigData->sampleFreq >> 1) / (sbrConfigData->noQmfBands);
+ if (FDKsbrEnc_InitSbrFastTransientDetector(
+ &hEnv->sbrFastTransientDetector, sbrConfigData->noQmfSlots,
+ bandwidth_qmf_slot, sbrConfigData->noQmfBands,
+ sbrConfigData->freqBandTable[0][0]))
+ return (1);
}
/* The transient detector has to be initialized also if the fast transient
detector was active, because the values from the transient detector
structure are used. */
- if(FDKsbrEnc_InitSbrTransientDetector (&hEnv->sbrTransientDetector,
- sbrConfigData->sbrSyntaxFlags,
- sbrConfigData->frameSize,
- sbrConfigData->sampleFreq,
- params,
- tran_fc,
- sbrConfigData->noQmfSlots,
- sbrConfigData->noQmfBands,
- hEnv->sbrExtractEnvelope.YBufferWriteOffset,
- hEnv->sbrExtractEnvelope.YBufferSzShift,
- frameShift,
- tran_off
- ))
- return(1);
-
+ if (FDKsbrEnc_InitSbrTransientDetector(
+ &hEnv->sbrTransientDetector, sbrConfigData->sbrSyntaxFlags,
+ sbrConfigData->frameSize, sbrConfigData->sampleFreq, params, tran_fc,
+ sbrConfigData->noQmfSlots, sbrConfigData->noQmfBands,
+ hEnv->sbrExtractEnvelope.YBufferWriteOffset,
+ hEnv->sbrExtractEnvelope.YBufferSzShift, frameShift, tran_off))
+ return (1);
sbrConfigData->xposCtrlSwitch = params->sbr_xpos_ctrl;
@@ -1471,83 +1493,80 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
return (0);
}
-INT sbrEncoder_Open(
- HANDLE_SBR_ENCODER *phSbrEncoder,
- INT nElements,
- INT nChannels,
- INT supportPS
- )
-{
+INT sbrEncoder_Open(HANDLE_SBR_ENCODER *phSbrEncoder, INT nElements,
+ INT nChannels, INT supportPS) {
INT i;
INT errorStatus = 1;
HANDLE_SBR_ENCODER hSbrEncoder = NULL;
- if (phSbrEncoder==NULL
- )
- {
+ if (phSbrEncoder == NULL) {
goto bail;
}
hSbrEncoder = GetRam_SbrEncoder();
- if (hSbrEncoder==NULL) {
+ if (hSbrEncoder == NULL) {
goto bail;
}
FDKmemclear(hSbrEncoder, sizeof(SBR_ENCODER));
- hSbrEncoder->pSBRdynamic_RAM = (UCHAR*)GetRam_SbrDynamic_RAM();
- hSbrEncoder->dynamicRam = hSbrEncoder->pSBRdynamic_RAM;
+ if (NULL ==
+ (hSbrEncoder->pSBRdynamic_RAM = (UCHAR *)GetRam_SbrDynamic_RAM())) {
+ goto bail;
+ }
+ hSbrEncoder->dynamicRam = hSbrEncoder->pSBRdynamic_RAM;
- for (i=0; i<nElements; i++) {
+ /* Create SBR elements */
+ for (i = 0; i < nElements; i++) {
hSbrEncoder->sbrElement[i] = GetRam_SbrElement(i);
- if (hSbrEncoder->sbrElement[i]==NULL) {
- goto bail;
+ if (hSbrEncoder->sbrElement[i] == NULL) {
+ goto bail;
}
FDKmemclear(hSbrEncoder->sbrElement[i], sizeof(SBR_ELEMENT));
- hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] = GetRam_Sbr_freqBandTableLO(i);
- hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] = GetRam_Sbr_freqBandTableHI(i);
- hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master = GetRam_Sbr_v_k_master(i);
- if ( (hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO]==NULL) ||
- (hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI]==NULL) ||
- (hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master==NULL) )
- {
- goto bail;
+ hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] =
+ GetRam_Sbr_freqBandTableLO(i);
+ hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] =
+ GetRam_Sbr_freqBandTableHI(i);
+ hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master =
+ GetRam_Sbr_v_k_master(i);
+ if ((hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] == NULL) ||
+ (hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] == NULL) ||
+ (hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master == NULL)) {
+ goto bail;
}
}
- for (i=0; i<nChannels; i++) {
+ /* Create SBR channels */
+ for (i = 0; i < nChannels; i++) {
hSbrEncoder->pSbrChannel[i] = GetRam_SbrChannel(i);
- if (hSbrEncoder->pSbrChannel[i]==NULL) {
- goto bail;
+ if (hSbrEncoder->pSbrChannel[i] == NULL) {
+ goto bail;
}
- if ( createEnvChannel(&hSbrEncoder->pSbrChannel[i]->hEnvChannel,
- i
- ,hSbrEncoder->dynamicRam
- ) )
- {
- goto bail;
+ if (createEnvChannel(&hSbrEncoder->pSbrChannel[i]->hEnvChannel, i,
+ hSbrEncoder->dynamicRam)) {
+ goto bail;
}
-
}
- for (i=0; i<fixMax(nChannels,(supportPS)?2:0); i++) {
+ /* Create QMF States */
+ for (i = 0; i < fixMax(nChannels, (supportPS) ? 2 : 0); i++) {
hSbrEncoder->QmfAnalysis[i].FilterStates = GetRam_Sbr_QmfStatesAnalysis(i);
- if (hSbrEncoder->QmfAnalysis[i].FilterStates==NULL) {
- goto bail;
+ if (hSbrEncoder->QmfAnalysis[i].FilterStates == NULL) {
+ goto bail;
}
}
+ /* Create Parametric Stereo handle */
if (supportPS) {
- if (PSEnc_Create(&hSbrEncoder->hParametricStereo))
- {
+ if (PSEnc_Create(&hSbrEncoder->hParametricStereo)) {
goto bail;
}
hSbrEncoder->qmfSynthesisPS.FilterStates = GetRam_PsQmfStatesSynthesis();
- if (hSbrEncoder->qmfSynthesisPS.FilterStates==NULL) {
+ if (hSbrEncoder->qmfSynthesisPS.FilterStates == NULL) {
goto bail;
}
- } /* supportPS */
+ } /* supportPS */
*phSbrEncoder = hSbrEncoder;
@@ -1560,56 +1579,74 @@ bail:
return errorStatus;
}
-static
-INT FDKsbrEnc_Reallocate(
- HANDLE_SBR_ENCODER hSbrEncoder,
- SBR_ELEMENT_INFO elInfo[(8)],
- const INT noElements)
-{
+static INT FDKsbrEnc_Reallocate(HANDLE_SBR_ENCODER hSbrEncoder,
+ SBR_ELEMENT_INFO elInfo[(8)],
+ const INT noElements) {
INT totalCh = 0;
INT totalQmf = 0;
INT coreEl;
- INT el=-1;
+ INT el = -1;
hSbrEncoder->lfeChIdx = -1; /* default value, until lfe found */
- for (coreEl=0; coreEl<noElements; coreEl++)
- {
+ for (coreEl = 0; coreEl < noElements; coreEl++) {
/* SBR only handles SCE and CPE's */
if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) {
el++;
} else {
if (elInfo[coreEl].elType == ID_LFE) {
- hSbrEncoder->lfeChIdx = elInfo[coreEl].ChannelIndex[0];
+ hSbrEncoder->lfeChIdx = elInfo[coreEl].ChannelIndex[0];
}
continue;
}
- SBR_ELEMENT_INFO *pelInfo = &elInfo[coreEl];
- HANDLE_SBR_ELEMENT hSbrElement = hSbrEncoder->sbrElement[el];
+ SBR_ELEMENT_INFO *pelInfo = &elInfo[coreEl];
+ HANDLE_SBR_ELEMENT hSbrElement = hSbrEncoder->sbrElement[el];
int ch;
- for ( ch = 0; ch < pelInfo->nChannelsInEl; ch++ ) {
+ for (ch = 0; ch < pelInfo->nChannelsInEl; ch++) {
hSbrElement->sbrChannel[ch] = hSbrEncoder->pSbrChannel[totalCh];
totalCh++;
}
/* analysis QMF */
- for ( ch = 0; ch < ((pelInfo->fParametricStereo)?2:pelInfo->nChannelsInEl); ch++ ) {
+ for (ch = 0;
+ ch < ((pelInfo->fParametricStereo) ? 2 : pelInfo->nChannelsInEl);
+ ch++) {
hSbrElement->elInfo.ChannelIndex[ch] = pelInfo->ChannelIndex[ch];
hSbrElement->hQmfAnalysis[ch] = &hSbrEncoder->QmfAnalysis[totalQmf++];
}
/* Copy Element info */
- hSbrElement->elInfo.elType = pelInfo->elType;
- hSbrElement->elInfo.instanceTag = pelInfo->instanceTag;
- hSbrElement->elInfo.nChannelsInEl = pelInfo->nChannelsInEl;
+ hSbrElement->elInfo.elType = pelInfo->elType;
+ hSbrElement->elInfo.instanceTag = pelInfo->instanceTag;
+ hSbrElement->elInfo.nChannelsInEl = pelInfo->nChannelsInEl;
hSbrElement->elInfo.fParametricStereo = pelInfo->fParametricStereo;
+ hSbrElement->elInfo.fDualMono = pelInfo->fDualMono;
} /* coreEl */
return 0;
}
+/*****************************************************************************
+
+ functionname: FDKsbrEnc_bsBufInit
+ description: initializes bitstream buffer
+ returns: initialized bitstream buffer in env encoder
+ input:
+ output: hEnv
+
+*****************************************************************************/
+static INT FDKsbrEnc_bsBufInit(HANDLE_SBR_ELEMENT hSbrElement,
+ int nBitstrDelay) {
+ UCHAR *bitstreamBuffer;
+
+ /* initialize the bitstream buffer */
+ bitstreamBuffer = hSbrElement->payloadDelayLine[nBitstrDelay];
+ FDKinitBitStream(&hSbrElement->CmonData.sbrBitbuf, bitstreamBuffer,
+ MAX_PAYLOAD_SIZE * sizeof(UCHAR), 0, BS_WRITER);
+ return (0);
+}
/*****************************************************************************
@@ -1620,113 +1657,109 @@ INT FDKsbrEnc_Reallocate(
output: hEnv
*****************************************************************************/
-static
-INT FDKsbrEnc_EnvInit (
- HANDLE_SBR_ELEMENT hSbrElement,
- sbrConfigurationPtr params,
- INT *coreBandWith,
- AUDIO_OBJECT_TYPE aot,
- int nBitstrDelay,
- int nElement,
- const int headerPeriod,
- ULONG statesInitFlag,
- int fTimeDomainDownsampling
- ,UCHAR *dynamic_RAM
- )
-{
- UCHAR *bitstreamBuffer;
+static INT FDKsbrEnc_EnvInit(HANDLE_SBR_ELEMENT hSbrElement,
+ sbrConfigurationPtr params, INT *coreBandWith,
+ AUDIO_OBJECT_TYPE aot, int nElement,
+ const int headerPeriod, ULONG statesInitFlag,
+ const SBRENC_DS_TYPE downsamplingMethod,
+ UCHAR *dynamic_RAM) {
int ch, i;
- if ((params->codecSettings.nChannels < 1) || (params->codecSettings.nChannels > MAX_NUM_CHANNELS)){
- return(1);
+ if ((params->codecSettings.nChannels < 1) ||
+ (params->codecSettings.nChannels > MAX_NUM_CHANNELS)) {
+ return (1);
}
- /* initialize the encoder handle and structs*/
- bitstreamBuffer = hSbrElement->payloadDelayLine[nBitstrDelay];
-
/* init and set syntax flags */
hSbrElement->sbrConfigData.sbrSyntaxFlags = 0;
switch (aot) {
- case AOT_ER_AAC_ELD:
- hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_LOW_DELAY;
- break;
- default:
- break;
+ case AOT_ER_AAC_ELD:
+ hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_LOW_DELAY;
+ break;
+ default:
+ break;
}
if (params->crcSbr) {
hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC;
}
- hSbrElement->sbrConfigData.noQmfBands = QMF_CHANNELS>>(2-params->downSampleFactor);
- switch (hSbrElement->sbrConfigData.noQmfBands)
- {
- case 64: hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize>>6;
- break;
- case 32: hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize>>5;
- break;
- default: hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize>>6;
- return(2);
+ hSbrElement->sbrConfigData.noQmfBands = 64 >> (2 - params->downSampleFactor);
+ switch (hSbrElement->sbrConfigData.noQmfBands) {
+ case 64:
+ hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 6;
+ break;
+ case 32:
+ hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 5;
+ break;
+ default:
+ hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 6;
+ return (2);
}
- FDKinitBitStream(&hSbrElement->CmonData.sbrBitbuf, bitstreamBuffer, MAX_PAYLOAD_SIZE*sizeof(UCHAR), 0, BS_WRITER);
-
/*
now initialize sbrConfigData, sbrHeaderData and sbrBitstreamData,
*/
hSbrElement->sbrConfigData.nChannels = params->codecSettings.nChannels;
- if(params->codecSettings.nChannels == 2)
- hSbrElement->sbrConfigData.stereoMode = params->stereoMode;
- else
- hSbrElement->sbrConfigData.stereoMode = SBR_MONO;
+ if (params->codecSettings.nChannels == 2) {
+ if ((hSbrElement->elInfo.elType == ID_CPE) &&
+ ((hSbrElement->elInfo.fDualMono == 1))) {
+ hSbrElement->sbrConfigData.stereoMode = SBR_LEFT_RIGHT;
+ } else {
+ hSbrElement->sbrConfigData.stereoMode = params->stereoMode;
+ }
+ } else {
+ hSbrElement->sbrConfigData.stereoMode = SBR_MONO;
+ }
- hSbrElement->sbrConfigData.frameSize = params->sbrFrameSize;
+ hSbrElement->sbrConfigData.frameSize = params->sbrFrameSize;
- hSbrElement->sbrConfigData.sampleFreq = params->downSampleFactor * params->codecSettings.sampleFreq;
+ hSbrElement->sbrConfigData.sampleFreq =
+ params->downSampleFactor * params->codecSettings.sampleFreq;
hSbrElement->sbrBitstreamData.CountSendHeaderData = 0;
- if (params->SendHeaderDataTime > 0 ) {
-
- if (headerPeriod==-1) {
-
- hSbrElement->sbrBitstreamData.NrSendHeaderData = (INT)(params->SendHeaderDataTime * hSbrElement->sbrConfigData.sampleFreq
- / (1000 * hSbrElement->sbrConfigData.frameSize));
- hSbrElement->sbrBitstreamData.NrSendHeaderData = fixMax(hSbrElement->sbrBitstreamData.NrSendHeaderData,1);
- }
- else {
+ if (params->SendHeaderDataTime > 0) {
+ if (headerPeriod == -1) {
+ hSbrElement->sbrBitstreamData.NrSendHeaderData = (INT)(
+ params->SendHeaderDataTime * hSbrElement->sbrConfigData.sampleFreq /
+ (1000 * hSbrElement->sbrConfigData.frameSize));
+ hSbrElement->sbrBitstreamData.NrSendHeaderData =
+ fixMax(hSbrElement->sbrBitstreamData.NrSendHeaderData, 1);
+ } else {
/* assure header period at least once per second */
- hSbrElement->sbrBitstreamData.NrSendHeaderData = fixMin(fixMax(headerPeriod,1),(hSbrElement->sbrConfigData.sampleFreq/hSbrElement->sbrConfigData.frameSize));
+ hSbrElement->sbrBitstreamData.NrSendHeaderData = fixMin(
+ fixMax(headerPeriod, 1), (hSbrElement->sbrConfigData.sampleFreq /
+ hSbrElement->sbrConfigData.frameSize));
}
- }
- else {
- hSbrElement->sbrBitstreamData.NrSendHeaderData = 0;
+ } else {
+ hSbrElement->sbrBitstreamData.NrSendHeaderData = 0;
}
hSbrElement->sbrHeaderData.sbr_data_extra = params->sbr_data_extra;
hSbrElement->sbrBitstreamData.HeaderActive = 0;
+ hSbrElement->sbrBitstreamData.rightBorderFIX = 0;
hSbrElement->sbrHeaderData.sbr_start_frequency = params->startFreq;
- hSbrElement->sbrHeaderData.sbr_stop_frequency = params->stopFreq;
+ hSbrElement->sbrHeaderData.sbr_stop_frequency = params->stopFreq;
hSbrElement->sbrHeaderData.sbr_xover_band = 0;
hSbrElement->sbrHeaderData.sbr_lc_stereo_mode = 0;
/* data_extra */
- if (params->sbr_xpos_ctrl!= SBR_XPOS_CTRL_DEFAULT)
- hSbrElement->sbrHeaderData.sbr_data_extra = 1;
+ if (params->sbr_xpos_ctrl != SBR_XPOS_CTRL_DEFAULT)
+ hSbrElement->sbrHeaderData.sbr_data_extra = 1;
hSbrElement->sbrHeaderData.sbr_amp_res = (AMP_RES)params->amp_res;
/* header_extra_1 */
- hSbrElement->sbrHeaderData.freqScale = params->freqScale;
+ hSbrElement->sbrHeaderData.freqScale = params->freqScale;
hSbrElement->sbrHeaderData.alterScale = params->alterScale;
hSbrElement->sbrHeaderData.sbr_noise_bands = params->sbr_noise_bands;
hSbrElement->sbrHeaderData.header_extra_1 = 0;
if ((params->freqScale != SBR_FREQ_SCALE_DEFAULT) ||
(params->alterScale != SBR_ALTER_SCALE_DEFAULT) ||
- (params->sbr_noise_bands != SBR_NOISE_BANDS_DEFAULT))
- {
- hSbrElement->sbrHeaderData.header_extra_1 = 1;
+ (params->sbr_noise_bands != SBR_NOISE_BANDS_DEFAULT)) {
+ hSbrElement->sbrHeaderData.header_extra_1 = 1;
}
/* header_extra_2 */
@@ -1734,95 +1767,92 @@ INT FDKsbrEnc_EnvInit (
hSbrElement->sbrHeaderData.sbr_limiter_gains = params->sbr_limiter_gains;
if ((hSbrElement->sbrConfigData.sampleFreq > 48000) &&
- (hSbrElement->sbrHeaderData.sbr_start_frequency >= 9))
- {
+ (hSbrElement->sbrHeaderData.sbr_start_frequency >= 9)) {
hSbrElement->sbrHeaderData.sbr_limiter_gains = SBR_LIMITER_GAINS_INFINITE;
}
hSbrElement->sbrHeaderData.sbr_interpol_freq = params->sbr_interpol_freq;
- hSbrElement->sbrHeaderData.sbr_smoothing_length = params->sbr_smoothing_length;
+ hSbrElement->sbrHeaderData.sbr_smoothing_length =
+ params->sbr_smoothing_length;
hSbrElement->sbrHeaderData.header_extra_2 = 0;
if ((params->sbr_limiter_bands != SBR_LIMITER_BANDS_DEFAULT) ||
(params->sbr_limiter_gains != SBR_LIMITER_GAINS_DEFAULT) ||
(params->sbr_interpol_freq != SBR_INTERPOL_FREQ_DEFAULT) ||
- (params->sbr_smoothing_length != SBR_SMOOTHING_LENGTH_DEFAULT))
- {
- hSbrElement->sbrHeaderData.header_extra_2 = 1;
+ (params->sbr_smoothing_length != SBR_SMOOTHING_LENGTH_DEFAULT)) {
+ hSbrElement->sbrHeaderData.header_extra_2 = 1;
}
- /* other switches */
- hSbrElement->sbrConfigData.useWaveCoding = params->useWaveCoding;
- hSbrElement->sbrConfigData.useParametricCoding = params->parametricCoding;
- hSbrElement->sbrConfigData.thresholdAmpResFF_m = params->threshold_AmpRes_FF_m;
- hSbrElement->sbrConfigData.thresholdAmpResFF_e = params->threshold_AmpRes_FF_e;
+ /* other switches */
+ hSbrElement->sbrConfigData.useWaveCoding = params->useWaveCoding;
+ hSbrElement->sbrConfigData.useParametricCoding = params->parametricCoding;
+ hSbrElement->sbrConfigData.thresholdAmpResFF_m =
+ params->threshold_AmpRes_FF_m;
+ hSbrElement->sbrConfigData.thresholdAmpResFF_e =
+ params->threshold_AmpRes_FF_e;
/* init freq band table */
- if(updateFreqBandTable(&hSbrElement->sbrConfigData,
- &hSbrElement->sbrHeaderData,
- params->downSampleFactor
- ))
- {
- return(1);
+ if (updateFreqBandTable(&hSbrElement->sbrConfigData,
+ &hSbrElement->sbrHeaderData,
+ params->downSampleFactor)) {
+ return (1);
}
/* now create envelope ext and QMF for each available channel */
- for ( ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++ ) {
-
- if ( initEnvChannel(&hSbrElement->sbrConfigData,
- &hSbrElement->sbrHeaderData,
- &hSbrElement->sbrChannel[ch]->hEnvChannel,
- params,
- statesInitFlag
- ,ch
- ,dynamic_RAM
- ) )
- {
- return(1);
- }
-
+ for (ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++) {
+ if (initEnvChannel(&hSbrElement->sbrConfigData, &hSbrElement->sbrHeaderData,
+ &hSbrElement->sbrChannel[ch]->hEnvChannel, params,
+ statesInitFlag, ch, dynamic_RAM)) {
+ return (1);
+ }
} /* nChannels */
/* reset and intialize analysis qmf */
- for ( ch = 0; ch < ((hSbrElement->elInfo.fParametricStereo)?2:hSbrElement->sbrConfigData.nChannels); ch++ )
- {
+ for (ch = 0; ch < ((hSbrElement->elInfo.fParametricStereo)
+ ? 2
+ : hSbrElement->sbrConfigData.nChannels);
+ ch++) {
int err;
- UINT qmfFlags = (hSbrElement->sbrConfigData.sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? QMF_FLAG_CLDFB : 0;
+ UINT qmfFlags =
+ (hSbrElement->sbrConfigData.sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
+ ? QMF_FLAG_CLDFB
+ : 0;
if (statesInitFlag)
qmfFlags &= ~QMF_FLAG_KEEP_STATES;
else
- qmfFlags |= QMF_FLAG_KEEP_STATES;
-
- err = qmfInitAnalysisFilterBank( hSbrElement->hQmfAnalysis[ch],
- (FIXP_QAS*)hSbrElement->hQmfAnalysis[ch]->FilterStates,
- hSbrElement->sbrConfigData.noQmfSlots,
- hSbrElement->sbrConfigData.noQmfBands,
- hSbrElement->sbrConfigData.noQmfBands,
- hSbrElement->sbrConfigData.noQmfBands,
- qmfFlags );
- if (0!=err) {
+ qmfFlags |= QMF_FLAG_KEEP_STATES;
+
+ err = qmfInitAnalysisFilterBank(
+ hSbrElement->hQmfAnalysis[ch],
+ (FIXP_QAS *)hSbrElement->hQmfAnalysis[ch]->FilterStates,
+ hSbrElement->sbrConfigData.noQmfSlots,
+ hSbrElement->sbrConfigData.noQmfBands,
+ hSbrElement->sbrConfigData.noQmfBands,
+ hSbrElement->sbrConfigData.noQmfBands, qmfFlags);
+ if (0 != err) {
return err;
}
}
/* */
hSbrElement->CmonData.xOverFreq = hSbrElement->sbrConfigData.xOverFreq;
- hSbrElement->CmonData.dynBwEnabled = (params->dynBwSupported && params->dynBwEnabled);
- hSbrElement->CmonData.dynXOverFreqEnc = FDKsbrEnc_SbrGetXOverFreq( hSbrElement, hSbrElement->CmonData.xOverFreq);
- for ( i = 0; i < 5; i++ )
- hSbrElement->dynXOverFreqDelay[i] = hSbrElement->CmonData.dynXOverFreqEnc;
- hSbrElement->CmonData.sbrNumChannels = hSbrElement->sbrConfigData.nChannels;
+ hSbrElement->CmonData.dynBwEnabled =
+ (params->dynBwSupported && params->dynBwEnabled);
+ hSbrElement->CmonData.dynXOverFreqEnc =
+ FDKsbrEnc_SbrGetXOverFreq(hSbrElement, hSbrElement->CmonData.xOverFreq);
+ for (i = 0; i < 5; i++)
+ hSbrElement->dynXOverFreqDelay[i] = hSbrElement->CmonData.dynXOverFreqEnc;
+ hSbrElement->CmonData.sbrNumChannels = hSbrElement->sbrConfigData.nChannels;
hSbrElement->sbrConfigData.dynXOverFreq = hSbrElement->CmonData.xOverFreq;
/* Update Bandwith to be passed to the core encoder */
*coreBandWith = hSbrElement->CmonData.xOverFreq;
- return(0);
- }
+ return (0);
+}
-INT sbrEncoder_GetInBufferSize(int noChannels)
-{
+INT sbrEncoder_GetInBufferSize(int noChannels) {
INT temp;
temp = (2048);
@@ -1835,53 +1865,42 @@ INT sbrEncoder_GetInBufferSize(int noChannels)
/*
* Encode Dummy SBR payload frames to fill the delay lines.
*/
-static
-INT FDKsbrEnc_DelayCompensation (
- HANDLE_SBR_ENCODER hEnvEnc,
- INT_PCM *timeBuffer
- )
-{
- int n, el;
-
- for (n=hEnvEnc->nBitstrDelay; n>0; n--)
- {
- for (el=0; el<hEnvEnc->noElements; el++)
- {
- if (FDKsbrEnc_EnvEncodeFrame(
- hEnvEnc,
- el,
- timeBuffer + hEnvEnc->downsampledOffset,
- hEnvEnc->sbrElement[el]->sbrConfigData.nChannels,
- NULL,
- NULL,
- 1
- ))
- return -1;
- }
- sbrEncoder_UpdateBuffers(hEnvEnc, timeBuffer);
+static INT FDKsbrEnc_DelayCompensation(HANDLE_SBR_ENCODER hEnvEnc,
+ INT_PCM *timeBuffer,
+ UINT timeBufferBufSize) {
+ int n, el;
+
+ for (n = hEnvEnc->nBitstrDelay; n > 0; n--) {
+ for (el = 0; el < hEnvEnc->noElements; el++) {
+ if (FDKsbrEnc_EnvEncodeFrame(
+ hEnvEnc, el,
+ timeBuffer + hEnvEnc->downsampledOffset / hEnvEnc->nChannels,
+ timeBufferBufSize, NULL, NULL, 1))
+ return -1;
}
- return 0;
+ sbrEncoder_UpdateBuffers(hEnvEnc, timeBuffer, timeBufferBufSize);
+ }
+ return 0;
}
-UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate, AUDIO_OBJECT_TYPE aot)
-{
- UINT newBitRate;
+UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels,
+ UINT coreSampleRate, AUDIO_OBJECT_TYPE aot) {
+ UINT newBitRate = bitRate;
INT index;
FDK_ASSERT(numChannels > 0 && numChannels <= 2);
if (aot == AOT_PS) {
- if (numChannels == 2) {
+ if (numChannels == 1) {
index = getPsTuningTableIndex(bitRate, &newBitRate);
if (index == INVALID_TABLE_IDX) {
bitRate = newBitRate;
}
- /* Set numChannels to 1 because for PS we need a SBR SCE (mono) element. */
- numChannels = 1;
} else {
return 0;
}
}
- index = getSbrTuningTableIndex(bitRate, numChannels, coreSampleRate, aot, &newBitRate);
+ index = getSbrTuningTableIndex(bitRate, numChannels, coreSampleRate, aot,
+ &newBitRate);
if (index != INVALID_TABLE_IDX) {
newBitRate = bitRate;
}
@@ -1889,523 +1908,640 @@ UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate
return newBitRate;
}
-UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot)
-{
- UINT isPossible=(AOT_PS==aot)?0:1;
+UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot) {
+ UINT isPossible = (AOT_PS == aot) ? 0 : 1;
return isPossible;
}
-INT sbrEncoder_Init(
- HANDLE_SBR_ENCODER hSbrEncoder,
- SBR_ELEMENT_INFO elInfo[(8)],
- int noElements,
- INT_PCM *inputBuffer,
- INT *coreBandwidth,
- INT *inputBufferOffset,
- INT *numChannels,
- INT *coreSampleRate,
- UINT *downSampleFactor,
- INT *frameLength,
- AUDIO_OBJECT_TYPE aot,
- int *delay,
- int transformFactor,
- const int headerPeriod,
- ULONG statesInitFlag
- )
-{
- HANDLE_ERROR_INFO errorInfo = noError;
- sbrConfiguration sbrConfig[(8)];
- INT error = 0;
- INT lowestBandwidth;
- /* Save input parameters */
- INT inputSampleRate = *coreSampleRate;
- int coreFrameLength = *frameLength;
- int inputBandWidth = *coreBandwidth;
- int inputChannels = *numChannels;
-
- int downsampledOffset = 0;
- int sbrOffset = 0;
- int downsamplerDelay = 0;
- int timeDomainDownsample = 0;
- int nBitstrDelay = 0;
- int highestSbrStartFreq, highestSbrStopFreq;
- int lowDelay = 0;
- int usePs = 0;
-
- /* check whether SBR setting is available for the current encoder configuration (bitrate, samplerate) */
- if (!sbrEncoder_IsSingleRatePossible(aot)) {
- *downSampleFactor = 2;
+/*****************************************************************************/
+/* */
+/*functionname: sbrEncoder_Init_delay */
+/*description: Determine Delay balancing and new encoder delay */
+/* */
+/*returns: - error status */
+/*input: - frame length of the core (i.e. e.g. AAC) */
+/* - number of channels */
+/* - downsample factor (1 for downsampled, 2 for dual-rate SBR) */
+/* - low delay presence */
+/* - ps presence */
+/* - downsampling method: QMF-, time domain or no downsampling */
+/* - various delay values (see DELAY_PARAM struct description) */
+/* */
+/*Example: Delay balancing for a HE-AACv1 encoder (time-domain downsampling) */
+/*========================================================================== */
+/* */
+/* +--------+ +--------+ +--------+ +--------+ +--------+ */
+/* |core | |ds 2:1 | |AAC | |QMF | |QMF | */
+/* +-+path +------------+ +-+core +-+analysis+-+overlap +-+ */
+/* | |offset | | | | | |32 bands| | | | */
+/* | +--------+ +--------+ +--------+ +--------+ +--------+ | */
+/* | core path +-------++ */
+/* | |QMF | */
+/*->+ +synth. +-> */
+/* | |64 bands| */
+/* | +-------++ */
+/* | +--------+ +--------+ +--------+ +--------+ | */
+/* | |SBR path| |QMF | |subband | |bs delay| | */
+/* +-+offset +-+analysis+-+sample +-+(full +-----------------------+ */
+/* | | |64 bands| |buffer | | frames)| */
+/* +--------+ +--------+ +--------+ +--------+ */
+/* SBR path */
+/* */
+/*****************************************************************************/
+static INT sbrEncoder_Init_delay(
+ const int coreFrameLength, /* input */
+ const int numChannels, /* input */
+ const int downSampleFactor, /* input */
+ const int lowDelay, /* input */
+ const int usePs, /* input */
+ const int is212, /* input */
+ const SBRENC_DS_TYPE downsamplingMethod, /* input */
+ DELAY_PARAM *hDelayParam /* input/output */
+) {
+ int delayCorePath = 0; /* delay in core path */
+ int delaySbrPath = 0; /* delay difference in QMF aka SBR path */
+ int delayInput2Core = 0; /* delay from the input to the core */
+ int delaySbrDec = 0; /* delay of the decoder's SBR module */
+
+ int delayCore = hDelayParam->delay; /* delay of the core */
+
+ /* Added delay by the SBR delay initialization */
+ int corePathOffset = 0; /* core path */
+ int sbrPathOffset = 0; /* sbr path */
+ int bitstreamDelay = 0; /* sbr path, framewise */
+
+ int flCore = coreFrameLength; /* core frame length */
+
+ int returnValue = 0; /* return value - 0 means: no error */
+
+ /* 1) Calculate actual delay for core and SBR path */
+ if (is212) {
+ delayCorePath = DELAY_COREPATH_ELDv2SBR(flCore, downSampleFactor);
+ delaySbrPath = DELAY_ELDv2SBR(flCore, downSampleFactor);
+ delaySbrDec = ((flCore) / 2) * (downSampleFactor);
+ } else if (lowDelay) {
+ delayCorePath = DELAY_COREPATH_ELDSBR(flCore, downSampleFactor);
+ delaySbrPath = DELAY_ELDSBR(flCore, downSampleFactor);
+ delaySbrDec = DELAY_QMF_POSTPROC(downSampleFactor);
+ } else if (usePs) {
+ delayCorePath = DELAY_COREPATH_PS(flCore, downSampleFactor);
+ delaySbrPath = DELAY_PS(flCore, downSampleFactor);
+ delaySbrDec = DELAY_COREPATH_SBR(flCore, downSampleFactor);
+ } else {
+ delayCorePath = DELAY_COREPATH_SBR(flCore, downSampleFactor);
+ delaySbrPath = DELAY_SBR(flCore, downSampleFactor);
+ delaySbrDec = DELAY_COREPATH_SBR(flCore, downSampleFactor);
+ }
+ delayCorePath += delayCore * downSampleFactor;
+ delayCorePath +=
+ (downsamplingMethod == SBRENC_DS_TIME) ? hDelayParam->dsDelay : 0;
+
+ /* 2) Manage coupling of paths */
+ if (downsamplingMethod == SBRENC_DS_QMF && delayCorePath > delaySbrPath) {
+ /* In case of QMF downsampling, both paths are coupled, i.e. the SBR path
+ offset would be added to both the SBR path and to the core path
+ as well, thus making it impossible to achieve delay balancing.
+ To overcome that problem, a framewise delay is added to the SBR path
+ first, until the overall delay of the core path is shorter than
+ the delay of the SBR path. When this is achieved, the missing delay
+ difference can be added as downsampled offset to the core path.
+ */
+ while (delayCorePath > delaySbrPath) {
+ /* Add one frame delay to SBR path */
+ delaySbrPath += flCore * downSampleFactor;
+ bitstreamDelay += 1;
}
+ }
+ /* 3) Calculate necessary additional delay to balance the paths */
+ if (delayCorePath > delaySbrPath) {
+ /* Delay QMF input */
+ while (delayCorePath > delaySbrPath + (int)flCore * (int)downSampleFactor) {
+ /* Do bitstream frame-wise delay balancing if there are
+ more than SBR framelength samples delay difference */
+ delaySbrPath += flCore * downSampleFactor;
+ bitstreamDelay += 1;
+ }
+ /* Multiply input offset by input channels */
+ corePathOffset = 0;
+ sbrPathOffset = (delayCorePath - delaySbrPath) * numChannels;
+ } else {
+ /* Delay AAC data */
+ /* Multiply downsampled offset by AAC core channels. Divide by 2 because of
+ half samplerate of downsampled data. */
+ corePathOffset = ((delaySbrPath - delayCorePath) * numChannels) >>
+ (downSampleFactor - 1);
+ sbrPathOffset = 0;
+ }
+ /* 4) Calculate delay from input to core */
+ if (usePs) {
+ delayInput2Core =
+ (DELAY_QMF_ANA(downSampleFactor) + DELAY_QMF_DS + DELAY_HYB_SYN) +
+ (downSampleFactor * corePathOffset) + 1;
+ } else if (downsamplingMethod == SBRENC_DS_TIME) {
+ delayInput2Core = corePathOffset + hDelayParam->dsDelay;
+ } else {
+ delayInput2Core = corePathOffset;
+ }
- if ( aot==AOT_PS ) {
- usePs = 1;
- }
- if ( aot==AOT_ER_AAC_ELD ) {
- lowDelay = 1;
- }
- else if ( aot==AOT_ER_AAC_LD ) {
- error = 1;
- goto bail;
- }
+ /* 6) Set output parameters */
+ hDelayParam->delay = FDKmax(delayCorePath, delaySbrPath); /* overall delay */
+ hDelayParam->sbrDecDelay = delaySbrDec; /* SBR decoder delay */
+ hDelayParam->delayInput2Core = delayInput2Core; /* delay input - core */
+ hDelayParam->bitstrDelay = bitstreamDelay; /* bitstream delay, in frames */
+ hDelayParam->corePathOffset = corePathOffset; /* offset added to core path */
+ hDelayParam->sbrPathOffset = sbrPathOffset; /* offset added to SBR path */
- /* Parametric Stereo */
- if ( usePs ) {
- if ( *numChannels == 2 && noElements == 1) {
- /* Override Element type in case of Parametric stereo */
- elInfo[0].elType = ID_SCE;
- elInfo[0].fParametricStereo = 1;
- elInfo[0].nChannelsInEl = 1;
- /* core encoder gets downmixed mono signal */
- *numChannels = 1;
- } else {
- error = 1;
- goto bail;
- }
- } /* usePs */
+ return returnValue;
+}
- /* set the core's sample rate */
- switch (*downSampleFactor) {
+/*****************************************************************************
+
+ functionname: sbrEncoder_Init
+ description: initializes the SBR encoder
+ returns: error status
+
+*****************************************************************************/
+INT sbrEncoder_Init(HANDLE_SBR_ENCODER hSbrEncoder,
+ SBR_ELEMENT_INFO elInfo[(8)], int noElements,
+ INT_PCM *inputBuffer, UINT inputBufferBufSize,
+ INT *coreBandwidth, INT *inputBufferOffset,
+ INT *numChannels, const UINT syntaxFlags,
+ INT *coreSampleRate, UINT *downSampleFactor,
+ INT *frameLength, AUDIO_OBJECT_TYPE aot, int *delay,
+ int transformFactor, const int headerPeriod,
+ ULONG statesInitFlag) {
+ HANDLE_ERROR_INFO errorInfo = noError;
+ sbrConfiguration sbrConfig[(8)];
+ INT error = 0;
+ INT lowestBandwidth;
+ /* Save input parameters */
+ INT inputSampleRate = *coreSampleRate;
+ int coreFrameLength = *frameLength;
+ int inputBandWidth = *coreBandwidth;
+ int inputChannels = *numChannels;
+
+ SBRENC_DS_TYPE downsamplingMethod = SBRENC_DS_NONE;
+ int highestSbrStartFreq, highestSbrStopFreq;
+ int lowDelay = 0;
+ int usePs = 0;
+ int is212 = 0;
+
+ DELAY_PARAM delayParam;
+
+ /* check whether SBR setting is available for the current encoder
+ * configuration (bitrate, samplerate) */
+ if (!sbrEncoder_IsSingleRatePossible(aot)) {
+ *downSampleFactor = 2;
+ }
+
+ if (aot == AOT_PS) {
+ usePs = 1;
+ }
+ if (aot == AOT_ER_AAC_ELD) {
+ lowDelay = 1;
+ } else if (aot == AOT_ER_AAC_LD) {
+ error = 1;
+ goto bail;
+ }
+
+ /* Parametric Stereo */
+ if (usePs) {
+ if (*numChannels == 2 && noElements == 1) {
+ /* Override Element type in case of Parametric stereo */
+ elInfo[0].elType = ID_SCE;
+ elInfo[0].fParametricStereo = 1;
+ elInfo[0].nChannelsInEl = 1;
+ /* core encoder gets downmixed mono signal */
+ *numChannels = 1;
+ } else {
+ error = 1;
+ goto bail;
+ }
+ } /* usePs */
+
+ /* set the core's sample rate */
+ switch (*downSampleFactor) {
case 1:
*coreSampleRate = inputSampleRate;
+ downsamplingMethod = SBRENC_DS_NONE;
break;
case 2:
- *coreSampleRate = inputSampleRate>>1;
+ *coreSampleRate = inputSampleRate >> 1;
+ downsamplingMethod = usePs ? SBRENC_DS_QMF : SBRENC_DS_TIME;
break;
default:
- *coreSampleRate = inputSampleRate>>1;
+ *coreSampleRate = inputSampleRate >> 1;
return 0; /* return error */
- }
+ }
- /* check whether SBR setting is available for the current encoder configuration (bitrate, coreSampleRate) */
- {
- int delayDiff = 0;
- int el, coreEl;
-
- /* Check if every element config is feasible */
- for (coreEl=0; coreEl<noElements; coreEl++)
- {
- /* SBR only handles SCE and CPE's */
- if (elInfo[coreEl].elType != ID_SCE && elInfo[coreEl].elType != ID_CPE) {
- continue;
- }
- /* check if desired configuration is available */
- if ( !FDKsbrEnc_IsSbrSettingAvail (elInfo[coreEl].bitRate, 0, elInfo[coreEl].nChannelsInEl, inputSampleRate, *coreSampleRate, aot) )
- {
- error = 1;
- goto bail;
- }
- }
+ /* check whether SBR setting is available for the current encoder
+ * configuration (bitrate, coreSampleRate) */
+ {
+ int el, coreEl;
- /* Determine Delay balancing and new encoder delay */
- if (lowDelay) {
- {
- delayDiff = (*delay * *downSampleFactor) + DELAY_ELD2SBR(coreFrameLength,*downSampleFactor);
- *delay = DELAY_ELDSBR(coreFrameLength,*downSampleFactor);
- }
- }
- else if (usePs) {
- delayDiff = (*delay * *downSampleFactor) + DELAY_AAC2PS(coreFrameLength,*downSampleFactor);
- *delay = DELAY_PS(coreFrameLength,*downSampleFactor);
- }
- else {
- delayDiff = DELAY_AAC2SBR(coreFrameLength,*downSampleFactor);
- delayDiff += (*delay * *downSampleFactor);
- *delay = DELAY_SBR(coreFrameLength,*downSampleFactor);
+ /* Check if every element config is feasible */
+ for (coreEl = 0; coreEl < noElements; coreEl++) {
+ /* SBR only handles SCE and CPE's */
+ if (elInfo[coreEl].elType != ID_SCE && elInfo[coreEl].elType != ID_CPE) {
+ continue;
}
-
- if (!usePs) {
- timeDomainDownsample = *downSampleFactor-1; /* activate time domain downsampler when downSampleFactor is != 1 */
+ /* check if desired configuration is available */
+ if (!FDKsbrEnc_IsSbrSettingAvail(elInfo[coreEl].bitRate, 0,
+ elInfo[coreEl].nChannelsInEl,
+ inputSampleRate, *coreSampleRate, aot)) {
+ error = 1;
+ goto bail;
}
+ }
-
- /* Take care about downsampled data bound to the SBR path */
- if (!timeDomainDownsample && delayDiff > 0) {
- /*
- * We must tweak the balancing into a situation where the downsampled path
- * is the one to be delayed, because delaying the QMF domain input, also delays
- * the downsampled audio, counteracting to the purpose of delay balancing.
- */
- while ( delayDiff > 0 )
- {
- /* Encoder delay increases */
- {
- *delay += coreFrameLength * *downSampleFactor;
- /* Add one frame delay to SBR path */
- delayDiff -= coreFrameLength * *downSampleFactor;
- }
- nBitstrDelay += 1;
- }
- } else
- {
- *delay += fixp_abs(delayDiff);
+ hSbrEncoder->nChannels = *numChannels;
+ hSbrEncoder->frameSize = coreFrameLength * *downSampleFactor;
+ hSbrEncoder->downsamplingMethod = downsamplingMethod;
+ hSbrEncoder->downSampleFactor = *downSampleFactor;
+ hSbrEncoder->estimateBitrate = 0;
+ hSbrEncoder->inputDataDelay = 0;
+ is212 = ((aot == AOT_ER_AAC_ELD) && (syntaxFlags & AC_LD_MPS)) ? 1 : 0;
+
+ /* Open SBR elements */
+ el = -1;
+ highestSbrStartFreq = highestSbrStopFreq = 0;
+ lowestBandwidth = 99999;
+
+ /* Loop through each core encoder element and get a matching SBR element
+ * config */
+ for (coreEl = 0; coreEl < noElements; coreEl++) {
+ /* SBR only handles SCE and CPE's */
+ if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) {
+ el++;
+ } else {
+ continue;
}
- if (delayDiff < 0) {
- /* Delay AAC data */
- delayDiff = -delayDiff;
- /* Multiply downsampled offset by AAC core channels. Divide by 2 because of half samplerate of downsampled data. */
- FDK_ASSERT(*downSampleFactor>0 && *downSampleFactor<=2);
- downsampledOffset = (delayDiff*(*numChannels))>>(*downSampleFactor-1);
- sbrOffset = 0;
+ /* Set parametric Stereo Flag. */
+ if (usePs) {
+ elInfo[coreEl].fParametricStereo = 1;
} else {
- /* Delay SBR input */
- if ( delayDiff > (int)coreFrameLength * (int)*downSampleFactor )
- {
- /* Do bitstream frame-wise delay balancing if we have more than SBR framelength samples delay difference */
- delayDiff -= coreFrameLength * *downSampleFactor;
- nBitstrDelay = 1;
- }
- /* Multiply input offset by input channels */
- sbrOffset = delayDiff*(*numChannels);
- downsampledOffset = 0;
+ elInfo[coreEl].fParametricStereo = 0;
}
- hSbrEncoder->nBitstrDelay = nBitstrDelay;
- hSbrEncoder->nChannels = *numChannels;
- hSbrEncoder->frameSize = coreFrameLength * *downSampleFactor;
- hSbrEncoder->fTimeDomainDownsampling = timeDomainDownsample;
- hSbrEncoder->downSampleFactor = *downSampleFactor;
- hSbrEncoder->estimateBitrate = 0;
- hSbrEncoder->inputDataDelay = 0;
-
-
- /* Open SBR elements */
- el = -1;
- highestSbrStartFreq = highestSbrStopFreq = 0;
- lowestBandwidth = 99999;
-
- /* Loop through each core encoder element and get a matching SBR element config */
- for (coreEl=0; coreEl<noElements; coreEl++)
- {
- /* SBR only handles SCE and CPE's */
- if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) {
- el++;
- } else {
- continue;
- }
- /* Set parametric Stereo Flag. */
- if (usePs) {
- elInfo[coreEl].fParametricStereo = 1;
- } else {
- elInfo[coreEl].fParametricStereo = 0;
- }
-
- /*
- * Init sbrConfig structure
- */
- if ( ! FDKsbrEnc_InitializeSbrDefaults ( &sbrConfig[el],
- *downSampleFactor,
- coreFrameLength,
- IS_LOWDELAY(aot)
- ) )
- {
- error = 1;
- goto bail;
- }
-
- /*
- * Modify sbrConfig structure according to Element parameters
- */
- if ( ! FDKsbrEnc_AdjustSbrSettings (&sbrConfig[el],
- elInfo[coreEl].bitRate,
- elInfo[coreEl].nChannelsInEl,
- *coreSampleRate,
- inputSampleRate,
- transformFactor,
- 24000,
- 0,
- 0, /* useSpeechConfig */
- 0, /* lcsMode */
- usePs, /* bParametricStereo */
- aot) )
- {
- error = 1;
- goto bail;
- }
-
- /* Find common frequency border for all SBR elements */
- highestSbrStartFreq = fixMax(highestSbrStartFreq, sbrConfig[el].startFreq);
- highestSbrStopFreq = fixMax(highestSbrStopFreq, sbrConfig[el].stopFreq);
-
- } /* first element loop */
-
- /* Set element count (can be less than core encoder element count) */
- hSbrEncoder->noElements = el+1;
+ /*
+ * Init sbrConfig structure
+ */
+ if (!FDKsbrEnc_InitializeSbrDefaults(&sbrConfig[el], *downSampleFactor,
+ coreFrameLength, IS_LOWDELAY(aot))) {
+ error = 1;
+ goto bail;
+ }
- FDKsbrEnc_Reallocate(hSbrEncoder,
- elInfo,
- noElements);
+ /*
+ * Modify sbrConfig structure according to Element parameters
+ */
+ if (!FDKsbrEnc_AdjustSbrSettings(
+ &sbrConfig[el], elInfo[coreEl].bitRate,
+ elInfo[coreEl].nChannelsInEl, *coreSampleRate, inputSampleRate,
+ transformFactor, 24000, 0, 0, /* useSpeechConfig */
+ 0, /* lcsMode */
+ usePs, /* bParametricStereo */
+ aot)) {
+ error = 1;
+ goto bail;
+ }
- for (el=0; el<hSbrEncoder->noElements; el++) {
+ /* Find common frequency border for all SBR elements */
+ highestSbrStartFreq =
+ fixMax(highestSbrStartFreq, sbrConfig[el].startFreq);
+ highestSbrStopFreq = fixMax(highestSbrStopFreq, sbrConfig[el].stopFreq);
- int bandwidth = *coreBandwidth;
+ } /* first element loop */
- /* Use lowest common bandwidth */
- sbrConfig[el].startFreq = highestSbrStartFreq;
- sbrConfig[el].stopFreq = highestSbrStopFreq;
+ /* Set element count (can be less than core encoder element count) */
+ hSbrEncoder->noElements = el + 1;
- /* initialize SBR element, and get core bandwidth */
- error = FDKsbrEnc_EnvInit(hSbrEncoder->sbrElement[el],
- &sbrConfig[el],
- &bandwidth,
- aot,
- nBitstrDelay,
- el,
- headerPeriod,
- statesInitFlag,
- hSbrEncoder->fTimeDomainDownsampling
- ,hSbrEncoder->dynamicRam
- );
+ FDKsbrEnc_Reallocate(hSbrEncoder, elInfo, noElements);
- if (error != 0) {
- error = 2;
- goto bail;
- }
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ int bandwidth = *coreBandwidth;
- /* Get lowest core encoder bandwidth to be returned later. */
- lowestBandwidth = fixMin(lowestBandwidth, bandwidth);
+ /* Use lowest common bandwidth */
+ sbrConfig[el].startFreq = highestSbrStartFreq;
+ sbrConfig[el].stopFreq = highestSbrStopFreq;
- } /* second element loop */
+ /* initialize SBR element, and get core bandwidth */
+ error = FDKsbrEnc_EnvInit(hSbrEncoder->sbrElement[el], &sbrConfig[el],
+ &bandwidth, aot, el, headerPeriod,
+ statesInitFlag, hSbrEncoder->downsamplingMethod,
+ hSbrEncoder->dynamicRam);
- /* Initialize a downsampler for each channel in each SBR element */
- if (hSbrEncoder->fTimeDomainDownsampling)
- {
- for (el=0; el<hSbrEncoder->noElements; el++)
- {
- HANDLE_SBR_ELEMENT hSbrEl = hSbrEncoder->sbrElement[el];
- INT Wc, ch;
+ if (error != 0) {
+ error = 2;
+ goto bail;
+ }
- /* Calculated required normalized cutoff frequency (Wc = 1.0 -> lowestBandwidth = inputSampleRate/2) */
- Wc = (2*lowestBandwidth)*1000 / inputSampleRate;
+ /* Get lowest core encoder bandwidth to be returned later. */
+ lowestBandwidth = fixMin(lowestBandwidth, bandwidth);
- for (ch=0; ch<hSbrEl->elInfo.nChannelsInEl; ch++)
- {
- FDKaacEnc_InitDownsampler (&hSbrEl->sbrChannel[ch]->downSampler, Wc, *downSampleFactor);
- FDK_ASSERT (hSbrEl->sbrChannel[ch]->downSampler.delay <=MAX_DS_FILTER_DELAY);
- }
+ } /* second element loop */
- downsamplerDelay = hSbrEl->sbrChannel[0]->downSampler.delay;
- } /* third element loop */
+ /* Initialize a downsampler for each channel in each SBR element */
+ if (hSbrEncoder->downsamplingMethod == SBRENC_DS_TIME) {
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ HANDLE_SBR_ELEMENT hSbrEl = hSbrEncoder->sbrElement[el];
+ INT Wc, ch;
- /* lfe */
- FDKaacEnc_InitDownsampler (&hSbrEncoder->lfeDownSampler, 0, *downSampleFactor);
+ Wc = 500; /* Cutoff frequency with full bandwidth */
- /* Add the resampler additional delay to get the final delay and buffer offset values. */
- if (sbrOffset > 0 || downsampledOffset <= ((downsamplerDelay * (*numChannels))>>(*downSampleFactor-1))) {
- sbrOffset += (downsamplerDelay - downsampledOffset) * (*numChannels) ;
- *delay += downsamplerDelay - downsampledOffset;
- downsampledOffset = 0;
- } else {
- downsampledOffset -= (downsamplerDelay * (*numChannels))>>(*downSampleFactor-1);
- sbrOffset = 0;
+ for (ch = 0; ch < hSbrEl->elInfo.nChannelsInEl; ch++) {
+ FDKaacEnc_InitDownsampler(&hSbrEl->sbrChannel[ch]->downSampler, Wc,
+ *downSampleFactor);
+ FDK_ASSERT(hSbrEl->sbrChannel[ch]->downSampler.delay <=
+ MAX_DS_FILTER_DELAY);
}
+ } /* third element loop */
- hSbrEncoder->inputDataDelay = downsamplerDelay;
- }
+ /* lfe */
+ FDKaacEnc_InitDownsampler(&hSbrEncoder->lfeDownSampler, 0,
+ *downSampleFactor);
+ }
- /* Assign core encoder Bandwidth */
- *coreBandwidth = lowestBandwidth;
+ /* Get delay information */
+ delayParam.dsDelay =
+ hSbrEncoder->sbrElement[0]->sbrChannel[0]->downSampler.delay;
+ delayParam.delay = *delay;
- /* Estimate sbr bitrate, 2.5 kBit/s per sbr channel */
- hSbrEncoder->estimateBitrate += 2500 * (*numChannels);
+ error = sbrEncoder_Init_delay(coreFrameLength, *numChannels,
+ *downSampleFactor, lowDelay, usePs, is212,
+ downsamplingMethod, &delayParam);
- /* initialize parametric stereo */
- if (usePs)
- {
- PSENC_CONFIG psEncConfig;
- FDK_ASSERT(hSbrEncoder->noElements == 1);
- INT psTuningTableIdx = getPsTuningTableIndex(elInfo[0].bitRate, NULL);
+ if (error != 0) {
+ error = 3;
+ goto bail;
+ }
- psEncConfig.frameSize = coreFrameLength; //sbrConfig.sbrFrameSize;
- psEncConfig.qmfFilterMode = 0;
- psEncConfig.sbrPsDelay = 0;
+ hSbrEncoder->nBitstrDelay = delayParam.bitstrDelay;
+ hSbrEncoder->sbrDecDelay = delayParam.sbrDecDelay;
+ hSbrEncoder->inputDataDelay = delayParam.delayInput2Core;
- /* tuning parameters */
- if (psTuningTableIdx != INVALID_TABLE_IDX) {
- psEncConfig.nStereoBands = psTuningTable[psTuningTableIdx].nStereoBands;
- psEncConfig.maxEnvelopes = psTuningTable[psTuningTableIdx].nEnvelopes;
- psEncConfig.iidQuantErrorThreshold = (FIXP_DBL)psTuningTable[psTuningTableIdx].iidQuantErrorThreshold;
+ /* Assign core encoder Bandwidth */
+ *coreBandwidth = lowestBandwidth;
- /* calculation is not quite linear, increased number of envelopes causes more bits */
- /* assume avg. 50 bits per frame for 10 stereo bands / 1 envelope configuration */
- hSbrEncoder->estimateBitrate += ( (((*coreSampleRate) * 5 * psEncConfig.nStereoBands * psEncConfig.maxEnvelopes) / hSbrEncoder->frameSize));
+ /* Estimate sbr bitrate, 2.5 kBit/s per sbr channel */
+ hSbrEncoder->estimateBitrate += 2500 * (*numChannels);
- } else {
- error = ERROR(CDI, "Invalid ps tuning table index.");
- goto bail;
- }
-
- qmfInitSynthesisFilterBank(&hSbrEncoder->qmfSynthesisPS,
- (FIXP_DBL*)hSbrEncoder->qmfSynthesisPS.FilterStates,
- hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots,
- hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands>>1,
- hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands>>1,
- hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands>>1,
- (statesInitFlag) ? 0 : QMF_FLAG_KEEP_STATES);
-
- if(errorInfo == noError){
- /* update delay */
- psEncConfig.sbrPsDelay = FDKsbrEnc_GetEnvEstDelay(&hSbrEncoder->sbrElement[0]->sbrChannel[0]->hEnvChannel.sbrExtractEnvelope);
-
- if(noError != (errorInfo = PSEnc_Init( hSbrEncoder->hParametricStereo,
- &psEncConfig,
- hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots,
- hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands
- ,hSbrEncoder->dynamicRam
- )))
- {
- errorInfo = handBack(errorInfo);
- }
- }
+ /* Initialize bitstream buffer for each element */
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ FDKsbrEnc_bsBufInit(hSbrEncoder->sbrElement[el], delayParam.bitstrDelay);
+ }
- /* QMF analysis + Hybrid analysis + Hybrid synthesis + QMF synthesis + downsampled input buffer delay */
- hSbrEncoder->inputDataDelay = (64*10/2) + (6*64) + (0) + (64*10/2-64+1) + ((*downSampleFactor)*downsampledOffset);
- }
+ /* initialize parametric stereo */
+ if (usePs) {
+ PSENC_CONFIG psEncConfig;
+ FDK_ASSERT(hSbrEncoder->noElements == 1);
+ INT psTuningTableIdx = getPsTuningTableIndex(elInfo[0].bitRate, NULL);
+
+ psEncConfig.frameSize = coreFrameLength; // sbrConfig.sbrFrameSize;
+ psEncConfig.qmfFilterMode = 0;
+ psEncConfig.sbrPsDelay = 0;
+
+ /* tuning parameters */
+ if (psTuningTableIdx != INVALID_TABLE_IDX) {
+ psEncConfig.nStereoBands = psTuningTable[psTuningTableIdx].nStereoBands;
+ psEncConfig.maxEnvelopes = psTuningTable[psTuningTableIdx].nEnvelopes;
+ psEncConfig.iidQuantErrorThreshold =
+ (FIXP_DBL)psTuningTable[psTuningTableIdx].iidQuantErrorThreshold;
+
+ /* calculation is not quite linear, increased number of envelopes causes
+ * more bits */
+ /* assume avg. 50 bits per frame for 10 stereo bands / 1 envelope
+ * configuration */
+ hSbrEncoder->estimateBitrate +=
+ ((((*coreSampleRate) * 5 * psEncConfig.nStereoBands *
+ psEncConfig.maxEnvelopes) /
+ hSbrEncoder->frameSize));
- hSbrEncoder->downsampledOffset = downsampledOffset;
- {
- hSbrEncoder->downmixSize = coreFrameLength*(*numChannels);
+ } else {
+ error = ERROR(CDI, "Invalid ps tuning table index.");
+ goto bail;
}
- hSbrEncoder->bufferOffset = sbrOffset;
- /* Delay Compensation: fill bitstream delay buffer with zero input signal */
- if ( hSbrEncoder->nBitstrDelay > 0 )
- {
- error = FDKsbrEnc_DelayCompensation (hSbrEncoder, inputBuffer);
- if (error != 0)
- goto bail;
+ qmfInitSynthesisFilterBank(
+ &hSbrEncoder->qmfSynthesisPS,
+ (FIXP_DBL *)hSbrEncoder->qmfSynthesisPS.FilterStates,
+ hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots,
+ hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1,
+ hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1,
+ hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1,
+ (statesInitFlag) ? 0 : QMF_FLAG_KEEP_STATES);
+
+ if (errorInfo == noError) {
+ /* update delay */
+ psEncConfig.sbrPsDelay =
+ FDKsbrEnc_GetEnvEstDelay(&hSbrEncoder->sbrElement[0]
+ ->sbrChannel[0]
+ ->hEnvChannel.sbrExtractEnvelope);
+
+ errorInfo =
+ PSEnc_Init(hSbrEncoder->hParametricStereo, &psEncConfig,
+ hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots,
+ hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands,
+ hSbrEncoder->dynamicRam);
}
+ }
- /* Set Output frame length */
- *frameLength = coreFrameLength * *downSampleFactor;
- /* Input buffer offset */
- *inputBufferOffset = fixMax(sbrOffset, downsampledOffset);
+ hSbrEncoder->downsampledOffset = delayParam.corePathOffset;
+ hSbrEncoder->bufferOffset = delayParam.sbrPathOffset;
+ *delay = delayParam.delay;
+ { hSbrEncoder->downmixSize = coreFrameLength * (*numChannels); }
+ /* Delay Compensation: fill bitstream delay buffer with zero input signal */
+ if (hSbrEncoder->nBitstrDelay > 0) {
+ error = FDKsbrEnc_DelayCompensation(hSbrEncoder, inputBuffer,
+ inputBufferBufSize);
+ if (error != 0) goto bail;
}
- return error;
+ /* Set Output frame length */
+ *frameLength = coreFrameLength * *downSampleFactor;
+ /* Input buffer offset */
+ *inputBufferOffset =
+ fixMax(delayParam.sbrPathOffset, delayParam.corePathOffset);
+ }
+
+ return error;
bail:
- /* Restore input settings */
- *coreSampleRate = inputSampleRate;
- *frameLength = coreFrameLength;
- *numChannels = inputChannels;
- *coreBandwidth = inputBandWidth;
-
- return error;
- }
-
-
-INT
-sbrEncoder_EncodeFrame( HANDLE_SBR_ENCODER hSbrEncoder,
- INT_PCM *samples,
- UINT timeInStride,
- UINT sbrDataBits[(8)],
- UCHAR sbrData[(8)][MAX_PAYLOAD_SIZE]
- )
-{
+ /* Restore input settings */
+ *coreSampleRate = inputSampleRate;
+ *frameLength = coreFrameLength;
+ *numChannels = inputChannels;
+ *coreBandwidth = inputBandWidth;
+
+ return error;
+}
+
+INT sbrEncoder_EncodeFrame(HANDLE_SBR_ENCODER hSbrEncoder, INT_PCM *samples,
+ UINT samplesBufSize, UINT sbrDataBits[(8)],
+ UCHAR sbrData[(8)][MAX_PAYLOAD_SIZE]) {
INT error;
int el;
- for (el=0; el<hSbrEncoder->noElements; el++)
- {
- if (hSbrEncoder->sbrElement[el] != NULL)
- {
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ if (hSbrEncoder->sbrElement[el] != NULL) {
error = FDKsbrEnc_EnvEncodeFrame(
- hSbrEncoder,
- el,
- samples + hSbrEncoder->downsampledOffset,
- timeInStride,
- &sbrDataBits[el],
- sbrData[el],
- 0
- );
- if (error)
- return error;
+ hSbrEncoder, el,
+ samples + hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels,
+ samplesBufSize, &sbrDataBits[el], sbrData[el], 0);
+ if (error) return error;
}
}
- if ( ( hSbrEncoder->lfeChIdx!=-1) && (hSbrEncoder->downSampleFactor > 1) )
- { /* lfe downsampler */
- INT nOutSamples;
+ error = FDKsbrEnc_Downsample(
+ hSbrEncoder,
+ samples + hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels,
+ samplesBufSize, hSbrEncoder->nChannels, &sbrDataBits[el], sbrData[el], 0);
+ if (error) return error;
- FDKaacEnc_Downsample(&hSbrEncoder->lfeDownSampler,
- samples + hSbrEncoder->downsampledOffset + hSbrEncoder->bufferOffset + hSbrEncoder->lfeChIdx,
- hSbrEncoder->frameSize,
- timeInStride,
- samples + hSbrEncoder->downsampledOffset + hSbrEncoder->lfeChIdx,
- &nOutSamples,
- hSbrEncoder->nChannels);
+ return 0;
+}
+INT sbrEncoder_UpdateBuffers(HANDLE_SBR_ENCODER hSbrEncoder,
+ INT_PCM *timeBuffer, UINT timeBufferBufSize) {
+ if (hSbrEncoder->downsampledOffset > 0) {
+ int c;
+ int nd = hSbrEncoder->downmixSize / hSbrEncoder->nChannels;
- }
+ for (c = 0; c < hSbrEncoder->nChannels; c++) {
+ /* Move delayed downsampled data */
+ FDKmemcpy(timeBuffer + timeBufferBufSize * c,
+ timeBuffer + timeBufferBufSize * c + nd,
+ sizeof(INT_PCM) *
+ (hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels));
+ }
+ } else {
+ int c;
+ for (c = 0; c < hSbrEncoder->nChannels; c++) {
+ /* Move delayed input data */
+ FDKmemcpy(
+ timeBuffer + timeBufferBufSize * c,
+ timeBuffer + timeBufferBufSize * c + hSbrEncoder->frameSize,
+ sizeof(INT_PCM) * hSbrEncoder->bufferOffset / hSbrEncoder->nChannels);
+ }
+ }
+ if (hSbrEncoder->nBitstrDelay > 0) {
+ int el;
+
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ FDKmemmove(
+ hSbrEncoder->sbrElement[el]->payloadDelayLine[0],
+ hSbrEncoder->sbrElement[el]->payloadDelayLine[1],
+ sizeof(UCHAR) * (hSbrEncoder->nBitstrDelay * MAX_PAYLOAD_SIZE));
+
+ FDKmemmove(&hSbrEncoder->sbrElement[el]->payloadDelayLineSize[0],
+ &hSbrEncoder->sbrElement[el]->payloadDelayLineSize[1],
+ sizeof(UINT) * (hSbrEncoder->nBitstrDelay));
+ }
+ }
return 0;
}
+INT sbrEncoder_SendHeader(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT error = -1;
+ if (hSbrEncoder) {
+ int el;
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ if ((hSbrEncoder->noElements == 1) &&
+ (hSbrEncoder->sbrElement[0]->elInfo.fParametricStereo == 1)) {
+ hSbrEncoder->sbrElement[el]->sbrBitstreamData.CountSendHeaderData =
+ hSbrEncoder->sbrElement[el]->sbrBitstreamData.NrSendHeaderData - 1;
+ } else {
+ hSbrEncoder->sbrElement[el]->sbrBitstreamData.CountSendHeaderData = 0;
+ }
+ }
+ error = 0;
+ }
+ return error;
+}
-INT sbrEncoder_UpdateBuffers(
- HANDLE_SBR_ENCODER hSbrEncoder,
- INT_PCM *timeBuffer
- )
- {
- if ( hSbrEncoder->downsampledOffset > 0 ) {
- /* Move delayed downsampled data */
- FDKmemcpy ( timeBuffer,
- timeBuffer + hSbrEncoder->downmixSize,
- sizeof(INT_PCM) * (hSbrEncoder->downsampledOffset) );
- } else {
- /* Move delayed input data */
- FDKmemcpy ( timeBuffer,
- timeBuffer + hSbrEncoder->nChannels * hSbrEncoder->frameSize,
- sizeof(INT_PCM) * hSbrEncoder->bufferOffset );
+INT sbrEncoder_ContainsHeader(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT sbrHeader = 1;
+ if (hSbrEncoder) {
+ int el;
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ sbrHeader &=
+ (hSbrEncoder->sbrElement[el]->sbrBitstreamData.HeaderActiveDelay == 1)
+ ? 1
+ : 0;
}
- if ( hSbrEncoder->nBitstrDelay > 0 )
- {
- int el;
+ }
+ return sbrHeader;
+}
- for (el=0; el<hSbrEncoder->noElements; el++)
- {
- FDKmemmove ( hSbrEncoder->sbrElement[el]->payloadDelayLine[0],
- hSbrEncoder->sbrElement[el]->payloadDelayLine[1],
- sizeof(UCHAR) * (hSbrEncoder->nBitstrDelay*MAX_PAYLOAD_SIZE) );
+INT sbrEncoder_GetHeaderDelay(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT delay = -1;
- FDKmemmove( &hSbrEncoder->sbrElement[el]->payloadDelayLineSize[0],
- &hSbrEncoder->sbrElement[el]->payloadDelayLineSize[1],
- sizeof(UINT) * (hSbrEncoder->nBitstrDelay) );
- }
+ if (hSbrEncoder) {
+ if ((hSbrEncoder->noElements == 1) &&
+ (hSbrEncoder->sbrElement[0]->elInfo.fParametricStereo == 1)) {
+ delay = hSbrEncoder->nBitstrDelay + 1;
+ } else {
+ delay = hSbrEncoder->nBitstrDelay;
}
- return 0;
- }
+ }
+ return delay;
+}
+INT sbrEncoder_GetBsDelay(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT delay = -1;
+ if (hSbrEncoder) {
+ delay = hSbrEncoder->nBitstrDelay;
+ }
+ return delay;
+}
-INT sbrEncoder_GetEstimateBitrate(HANDLE_SBR_ENCODER hSbrEncoder)
-{
+INT sbrEncoder_SAPPrepare(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT error = -1;
+ if (hSbrEncoder) {
+ int el;
+ for (el = 0; el < hSbrEncoder->noElements; el++) {
+ hSbrEncoder->sbrElement[el]->sbrBitstreamData.rightBorderFIX = 1;
+ }
+ error = 0;
+ }
+ return error;
+}
+
+INT sbrEncoder_GetEstimateBitrate(HANDLE_SBR_ENCODER hSbrEncoder) {
INT estimateBitrate = 0;
- if(hSbrEncoder) {
+ if (hSbrEncoder) {
estimateBitrate += hSbrEncoder->estimateBitrate;
}
return estimateBitrate;
}
-INT sbrEncoder_GetInputDataDelay(HANDLE_SBR_ENCODER hSbrEncoder)
-{
+INT sbrEncoder_GetInputDataDelay(HANDLE_SBR_ENCODER hSbrEncoder) {
INT delay = -1;
- if(hSbrEncoder) {
+ if (hSbrEncoder) {
delay = hSbrEncoder->inputDataDelay;
}
return delay;
}
+INT sbrEncoder_GetSbrDecDelay(HANDLE_SBR_ENCODER hSbrEncoder) {
+ INT delay = -1;
-INT sbrEncoder_GetLibInfo( LIB_INFO *info )
-{
+ if (hSbrEncoder) {
+ delay = hSbrEncoder->sbrDecDelay;
+ }
+ return delay;
+}
+
+INT sbrEncoder_GetLibInfo(LIB_INFO *info) {
int i;
if (info == NULL) {
@@ -2421,7 +2557,8 @@ INT sbrEncoder_GetLibInfo( LIB_INFO *info )
info += i;
info->module_id = FDK_SBRENC;
- info->version = LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2);
+ info->version =
+ LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2);
LIB_VERSION_STRING(info);
#ifdef __ANDROID__
info->build_date = "";
@@ -2433,10 +2570,7 @@ INT sbrEncoder_GetLibInfo( LIB_INFO *info )
info->title = "SBR Encoder";
/* Set flags */
- info->flags = 0
- | CAPF_SBR_HQ
- | CAPF_SBR_PS_MPEG
- ;
+ info->flags = 0 | CAPF_SBR_HQ | CAPF_SBR_PS_MPEG;
/* End of flags */
return 0;