Commit 3aec97e3 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi

Encoder downsampled SBR

* AAC-Encoder

   - Introduce optional AACENC_SBR_RATIO encoder API parameter to configure
     dualrate or downsampled SBR explicitely. ELD makes use of downsampled SBR
     in default configuration.
     Modified file(s):
        documentation\aacEncoder.pdf
        libAACenc\include\aacenc_lib.h
        libAACenc\src\aacenc.h
        libAACenc\src\aacenc_lib.cpp

* SBR-Encoder

   - Implement downsampled SBR feature.
   - Revise sbr tuning parameter selection.
     Modified file(s):
        libSBRenc\include\sbr_encoder.h
        libSBRenc\src\bit_sbr.h
        libSBRenc\src\env_est.cpp
        libSBRenc\src\mh_det.cpp
        libSBRenc\src\nf_est.cpp
        libSBRenc\src\ps_main.cpp
        libSBRenc\src\sbr.h
        libSBRenc\src\sbr_def.h
        libSBRenc\src\sbr_encoder.cpp
        libSBRenc\src\sbr_rom.cpp
        libSBRenc\src\sbr_rom.h
        libSBRenc\src\sbrenc_freq_sca.cpp
        libSBRenc\src\sbrenc_freq_sca.h
        libSBRenc\src\ton_corr.cpp

Bug 9428126

Change-Id: I731720a10829272acaaf70b84525df00a09ff3d2
parent 7ad97579
...@@ -316,7 +316,8 @@ if the parameter was not set from extern. The bitrate depends on the number of e ...@@ -316,7 +316,8 @@ if the parameter was not set from extern. The bitrate depends on the number of e
channels and sampling rate and is determined as follows. channels and sampling rate and is determined as follows.
\code \code
AAC-LC (AOT_AAC_LC): 1.5 bits per sample AAC-LC (AOT_AAC_LC): 1.5 bits per sample
HE-AAC (AOT_SBR): 0.625 bits per sample HE-AAC (AOT_SBR): 0.625 bits per sample (dualrate sbr)
HE-AAC (AOT_SBR): 1.125 bits per sample (downsampled sbr)
HE-AAC v2 (AOT_PS): 0.5 bits per sample HE-AAC v2 (AOT_PS): 0.5 bits per sample
\endcode \endcode
...@@ -416,8 +417,9 @@ determines the maximum allowed bitrate for AAC-LC. For HE-AAC and HE-AAC v2 a li ...@@ -416,8 +417,9 @@ determines the maximum allowed bitrate for AAC-LC. For HE-AAC and HE-AAC v2 a li
look-up table is used. look-up table is used.
A good working point in terms of audio quality, sampling rate and bitrate, is at 1 to 1.5 A good working point in terms of audio quality, sampling rate and bitrate, is at 1 to 1.5
bits/audio sample for AAC-LC, 0.625 bits/audio sample for HE-AAC and 0.5 bits/audio sample bits/audio sample for AAC-LC, 0.625 bits/audio sample for dualrate HE-AAC, 1.125 bits/audio sample
for HE-AAC v2. For example for one channel with a sampling frequency of 48 kHz, the range from for downsampled HE-AAC and 0.5 bits/audio sample for HE-AAC v2.
For example for one channel with a sampling frequency of 48 kHz, the range from
48 kbit/s to 72 kbit/s achieves reasonable audio quality for AAC-LC. 48 kbit/s to 72 kbit/s achieves reasonable audio quality for AAC-LC.
For HE-AAC and HE-AAC v2 the lowest possible audio input sampling frequency is 16 kHz because then the For HE-AAC and HE-AAC v2 the lowest possible audio input sampling frequency is 16 kHz because then the
...@@ -434,7 +436,7 @@ quality at that bitrate than HE-AAC or HE-AAC v2. ...@@ -434,7 +436,7 @@ quality at that bitrate than HE-AAC or HE-AAC v2.
The following table provides an overview of recommended encoder configuration parameters The following table provides an overview of recommended encoder configuration parameters
which we determined by virtue of numerous listening tests. which we determined by virtue of numerous listening tests.
\subsection reommendedConfigLC AAC-LC, HE-AAC, HE-AACv2. \subsection reommendedConfigLC AAC-LC, HE-AAC, HE-AACv2 in Dualrate SBR mode.
\verbatim \verbatim
----------------------------------------------------------------------------------- -----------------------------------------------------------------------------------
Audio Object Type | Bit Rate Range | Supported | Preferred | No. of Audio Object Type | Bit Rate Range | Supported | Preferred | No. of
...@@ -457,8 +459,8 @@ AAC LC + SBR | 64000 - 128000 | 32.00, 44.10, 48.00 | 48.00 | ...@@ -457,8 +459,8 @@ AAC LC + SBR | 64000 - 128000 | 32.00, 44.10, 48.00 | 48.00 |
-------------------+------------------+-----------------------+------------+------- -------------------+------------------+-----------------------+------------+-------
AAC LC + SBR | 64000 - 69999 | 32.00, 44.10, 48.00 | 32.00 | 5, 5.1 AAC LC + SBR | 64000 - 69999 | 32.00, 44.10, 48.00 | 32.00 | 5, 5.1
AAC LC + SBR | 70000 - 159999 | 32.00, 44.10, 48.00 | 44.10 | 5, 5.1 AAC LC + SBR | 70000 - 159999 | 32.00, 44.10, 48.00 | 44.10 | 5, 5.1
AAC LC + SBR | 160000 - 319999 | 32.00, 44.10, 48.00 | 48.00 | 5, 5.1 AAC LC + SBR | 160000 - 245999 | 32.00, 44.10, 48.00 | 48.00 | 5
AAC LC + SBR | 320000 - 640000 | 64.00, 88.20, 96.00 | 96.00 | 5, 5.1 AAC LC + SBR | 160000 - 265999 | 32.00, 44.10, 48.00 | 48.00 | 5.1
-------------------+------------------+-----------------------+------------+------- -------------------+------------------+-----------------------+------------+-------
AAC LC | 8000 - 15999 | 11.025, 12.00, 16.00 | 12.00 | 1 AAC LC | 8000 - 15999 | 11.025, 12.00, 16.00 | 12.00 | 1
AAC LC | 16000 - 23999 | 16.00 | 16.00 | 1 AAC LC | 16000 - 23999 | 16.00 | 16.00 | 1
...@@ -481,7 +483,7 @@ AAC LC | 280000 - 800000 | 32.00, 44.10, 48.00 | 44.10 | 5, ...@@ -481,7 +483,7 @@ AAC LC | 280000 - 800000 | 32.00, 44.10, 48.00 | 44.10 | 5,
----------------------------------------------------------------------------------- -----------------------------------------------------------------------------------
\endverbatim \n \endverbatim \n
\subsection reommendedConfigLD AAC-LD, AAC-ELD, AAC-ELD with SBR. \subsection reommendedConfigLD AAC-LD, AAC-ELD, AAC-ELD with SBR in Dualrate SBR mode.
\verbatim \verbatim
----------------------------------------------------------------------------------- -----------------------------------------------------------------------------------
Audio Object Type | Bit Rate Range | Supported | Preferred | No. of Audio Object Type | Bit Rate Range | Supported | Preferred | No. of
...@@ -489,18 +491,20 @@ Audio Object Type | Bit Rate Range | Supported | Preferred | No. ...@@ -489,18 +491,20 @@ Audio Object Type | Bit Rate Range | Supported | Preferred | No.
| | [kHz] | Rate | | | [kHz] | Rate |
| | | [kHz] | | | | [kHz] |
-------------------+------------------+-----------------------+------------+------- -------------------+------------------+-----------------------+------------+-------
ELD + SBR | 16000 - 24999 | 32.00 - 44.10 | 32.00 | 1 ELD + SBR | 18000 - 24999 | 32.00 - 44.10 | 32.00 | 1
ELD + SBR | 25000 - 31999 | 32.00 - 48.00 | 32.00 | 1 ELD + SBR | 25000 - 31999 | 32.00 - 48.00 | 32.00 | 1
ELD + SBR | 32000 - 64000 | 32.00 - 48.00 | 48.00 | 1 ELD + SBR | 32000 - 64000 | 32.00 - 48.00 | 48.00 | 1
-------------------+------------------+-----------------------+------------+------- -------------------+------------------+-----------------------+------------+-------
ELD + SBR | 32000 - 51999 | 32.00 - 48.00 | 44.10 | 2 ELD + SBR | 32000 - 51999 | 32.00 - 48.00 | 44.10 | 2
ELD + SBR | 52000 - 128000 | 32.00 - 48.00 | 48.00 | 2 ELD + SBR | 52000 - 128000 | 32.00 - 48.00 | 48.00 | 2
-------------------+------------------+-----------------------+------------+------- -------------------+------------------+-----------------------+------------+-------
ELD + SBR | 72000 - 192000 | 44.10 - 48.00 | 48.00 | 3 ELD + SBR | 72000 - 160000 | 44.10 - 48.00 | 48.00 | 3
-------------------+------------------+-----------------------+------------+------- -------------------+------------------+-----------------------+------------+-------
ELD + SBR | 96000 - 256000 | 44.10 - 48.00 | 48.00 | 4 ELD + SBR | 96000 - 212000 | 44.10 - 48.00 | 48.00 | 4
-------------------+------------------+-----------------------+------------+------- -------------------+------------------+-----------------------+------------+-------
ELD + SBR | 120000 - 320000 | 44.10 - 48.00 | 48.00 | 5 ELD + SBR | 120000 - 246000 | 44.10 - 48.00 | 48.00 | 5
-------------------+------------------+-----------------------+------------+-------
ELD + SBR | 120000 - 266000 | 44.10 - 48.00 | 48.00 | 5.1
-------------------+------------------+-----------------------+------------+------- -------------------+------------------+-----------------------+------------+-------
LD, ELD | 16000 - 19999 | 16.00 - 24.00 | 16.00 | 1 LD, ELD | 16000 - 19999 | 16.00 - 24.00 | 16.00 | 1
LD, ELD | 20000 - 39999 | 16.00 - 32.00 | 24.00 | 1 LD, ELD | 20000 - 39999 | 16.00 - 32.00 | 24.00 | 1
...@@ -531,13 +535,33 @@ LD, ELD | 340000 - 960000 | 44.10 - 48.00 | 48.00 | ...@@ -531,13 +535,33 @@ LD, ELD | 340000 - 960000 | 44.10 - 48.00 | 48.00 |
----------------------------------------------------------------------------------- -----------------------------------------------------------------------------------
\endverbatim \n \endverbatim \n
\subsection reommendedConfigELD AAC-ELD with SBR in Downsampled SBR mode.
\verbatim
-----------------------------------------------------------------------------------
Audio Object Type | Bit Rate Range | Supported | Preferred | No. of
| [bit/s] | Sampling Rates | Sampl. | Chan.
| | [kHz] | Rate |
| | | [kHz] |
-------------------+------------------+-----------------------+------------+-------
ELD + SBR | 18000 - 24999 | 16.00 - 22.05 | 22.05 | 1
(downsampled SBR) | 25000 - 35999 | 22.05 - 32.00 | 24.00 | 1
| 36000 - 64000 | 32.00 - 48.00 | 32.00 | 1
-----------------------------------------------------------------------------------
\endverbatim \n
\page ENCODERBEHAVIOUR Encoder Behaviour \page ENCODERBEHAVIOUR Encoder Behaviour
\section BEHAVIOUR_BANDWIDTH Bandwidth \section BEHAVIOUR_BANDWIDTH Bandwidth
The FDK AAC encoder usually does not use the full frequency range of the input signal, but restricts the bandwidth The FDK AAC encoder usually does not use the full frequency range of the input signal, but restricts the bandwidth
according to certain library-internal settings. They can be changed in the table "bandWidthTable" in the according to certain library-internal settings. They can be changed in the table "bandWidthTable" in the
file bandwidth.cpp (if available), or via command-line argument "-w" (see chapter \ref CommandLineUsage). file bandwidth.cpp (if available).
The encoder API provides the ::AACENC_BANDWIDTH parameter to adjust the bandwidth explicitly.
\code
aacEncoder_SetParam(hAacEncoder, AACENC_BANDWIDTH, value);
\endcode
However it is not recommended to change these settings, because they are based on numerious listening However it is not recommended to change these settings, because they are based on numerious listening
tests and careful tweaks to ensure the best overall encoding quality. tests and careful tweaks to ensure the best overall encoding quality.
...@@ -638,7 +662,6 @@ an MPEG-2 AOT is choosen since PNS is an MPEG-4 AAC feature. ...@@ -638,7 +662,6 @@ an MPEG-2 AOT is choosen since PNS is an MPEG-4 AAC feature.
If SBR is activated, the encoder automatically deactivates PNS internally. If TNS is disabled but PNS is allowed, If SBR is activated, the encoder automatically deactivates PNS internally. If TNS is disabled but PNS is allowed,
the encoder deactivates PNS calculation internally. the encoder deactivates PNS calculation internally.
*/ */
#ifndef _AAC_ENC_LIB_H_ #ifndef _AAC_ENC_LIB_H_
...@@ -875,6 +898,15 @@ typedef enum ...@@ -875,6 +898,15 @@ typedef enum
- 0: MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE). (default) - 0: MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE). (default)
- 1: WAVE file format channel ordering (e. g. 5.1: L, R, C, LFE, SL, SR). */ - 1: WAVE file format channel ordering (e. g. 5.1: L, R, C, LFE, SL, SR). */
AACENC_SBR_RATIO = 0x0108, /*!< Controls activation of downsampled SBR. With downsampled SBR, the delay will be
shorter. On the other hand, for achieving the same quality level, downsampled SBR
needs more bits than dual-rate SBR.
With downsampled SBR, the AAC encoder will work at the same sampling rate as the
SBR encoder (single rate).
Downsampled SBR is supported for AAC-ELD and HE-AACv1.
- 1: Downsampled SBR (default for ELD).
- 2: Dual-rate SBR (default for HE-AAC). */
AACENC_AFTERBURNER = 0x0200, /*!< This parameter controls the use of the afterburner feature. AACENC_AFTERBURNER = 0x0200, /*!< This parameter controls the use of the afterburner feature.
The afterburner is a type of analysis by synthesis algorithm which increases the The afterburner is a type of analysis by synthesis algorithm which increases the
audio quality but also the required processing power. It is recommended to always audio quality but also the required processing power. It is recommended to always
......
...@@ -204,6 +204,8 @@ struct AACENC_CONFIG { ...@@ -204,6 +204,8 @@ struct AACENC_CONFIG {
INT maxBitsPerFrame; /* maximum number of bits in AU */ INT maxBitsPerFrame; /* maximum number of bits in AU */
INT bitreservoir; /* size of bitreservoir */ INT bitreservoir; /* size of bitreservoir */
UINT sbrRatio; /* sbr sampling rate ratio: dual- or single-rate */
UCHAR useTns; /* flag: use temporal noise shaping */ UCHAR useTns; /* flag: use temporal noise shaping */
UCHAR usePns; /* flag: use perceptual noise substitution */ UCHAR usePns; /* flag: use perceptual noise substitution */
UCHAR useIS; /* flag: use intensity coding */ UCHAR useIS; /* flag: use intensity coding */
......
...@@ -98,7 +98,7 @@ amm-info@iis.fraunhofer.de ...@@ -98,7 +98,7 @@ amm-info@iis.fraunhofer.de
/* Encoder library info */ /* Encoder library info */
#define AACENCODER_LIB_VL0 3 #define AACENCODER_LIB_VL0 3
#define AACENCODER_LIB_VL1 4 #define AACENCODER_LIB_VL1 4
#define AACENCODER_LIB_VL2 8 #define AACENCODER_LIB_VL2 9
#define AACENCODER_LIB_TITLE "AAC Encoder" #define AACENCODER_LIB_TITLE "AAC Encoder"
#define AACENCODER_LIB_BUILD_DATE __DATE__ #define AACENCODER_LIB_BUILD_DATE __DATE__
#define AACENCODER_LIB_BUILD_TIME __TIME__ #define AACENCODER_LIB_BUILD_TIME __TIME__
...@@ -118,7 +118,7 @@ amm-info@iis.fraunhofer.de ...@@ -118,7 +118,7 @@ amm-info@iis.fraunhofer.de
#define SBL(fl) (fl/8) /*!< Short block length (hardcoded to 8 short blocks per long block) */ #define SBL(fl) (fl/8) /*!< Short block length (hardcoded to 8 short blocks per long block) */
#define BSLA(fl) (4*SBL(fl)+SBL(fl)/2) /*!< AAC block switching look-ahead */ #define BSLA(fl) (4*SBL(fl)+SBL(fl)/2) /*!< AAC block switching look-ahead */
#define DELAY_AAC(fl) (fl+BSLA(fl)) /*!< MDCT + blockswitching */ #define DELAY_AAC(fl) (fl+BSLA(fl)) /*!< MDCT + blockswitching */
#define DELAY_AACELD(fl) ( (fl) + ((fl)/2) ) /*!< ELD FB delay */ #define DELAY_AACELD(fl) ((fl)/2) /*!< ELD FB delay (no framing delay included) */
#define INPUTBUFFER_SIZE (1537+100+2048) #define INPUTBUFFER_SIZE (1537+100+2048)
...@@ -166,7 +166,8 @@ typedef struct { ...@@ -166,7 +166,8 @@ typedef struct {
UCHAR userMetaDataMode; /*!< Meta data library configuration. */ UCHAR userMetaDataMode; /*!< Meta data library configuration. */
UCHAR userSbrEnabled; UCHAR userSbrEnabled; /*!< Enable SBR for ELD. */
UINT userSbrRatio; /*!< SBR sampling rate ratio. Dual- or single-rate. */
} USER_PARAM; } USER_PARAM;
...@@ -229,7 +230,7 @@ struct AACENCODER ...@@ -229,7 +230,7 @@ struct AACENCODER
UINT encoder_modis; UINT encoder_modis;
/* Capabity flags */ /* Capability flags */
UINT CAPF_tpEnc; UINT CAPF_tpEnc;
} ; } ;
...@@ -255,6 +256,20 @@ static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig) ...@@ -255,6 +256,20 @@ static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig)
return ( sbrUsed ); return ( sbrUsed );
} }
static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType)
{
INT psUsed = 0;
if ( (audioObjectType==AOT_PS)
|| (audioObjectType==AOT_MP2_PS)
|| (audioObjectType==AOT_DABPLUS_PS)
|| (audioObjectType==AOT_DRM_MPEG_PS) )
{
psUsed = 1;
}
return ( psUsed );
}
/**************************************************************************** /****************************************************************************
Allocate Encoder Allocate Encoder
****************************************************************************/ ****************************************************************************/
...@@ -449,6 +464,14 @@ AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig, ...@@ -449,6 +464,14 @@ AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig,
config->userAncDataRate = 0; config->userAncDataRate = 0;
/* SBR rate is set to 0 here, which means it should be set automatically
in FDKaacEnc_AdjustEncSettings() if the user did not set a rate
expilicitely. */
config->userSbrRatio = 0;
/* SBR enable set to -1 means to inquire ELD audio configurator for reasonable configuration. */
config->userSbrEnabled = -1;
return AAC_ENC_OK; return AAC_ENC_OK;
} }
...@@ -483,6 +506,7 @@ INT aacEncoder_LimitBitrate( ...@@ -483,6 +506,7 @@ INT aacEncoder_LimitBitrate(
INT bitRate, INT bitRate,
const INT nSubFrames, const INT nSubFrames,
const INT sbrActive, const INT sbrActive,
const INT sbrDownSampleRate,
const AUDIO_OBJECT_TYPE aot const AUDIO_OBJECT_TYPE aot
) )
{ {
...@@ -492,8 +516,7 @@ INT aacEncoder_LimitBitrate( ...@@ -492,8 +516,7 @@ INT aacEncoder_LimitBitrate(
FDKaacEnc_InitChannelMapping(channelMode, CH_ORDER_MPEG, &cm); FDKaacEnc_InitChannelMapping(channelMode, CH_ORDER_MPEG, &cm);
if (sbrActive) { if (sbrActive) {
/* Assume SBR rate ratio of 2:1 */ coreSamplingRate = samplingRate >> (sbrEncoder_IsSingleRatePossible(aot) ? (sbrDownSampleRate-1):1);
coreSamplingRate = samplingRate / 2;
} else { } else {
coreSamplingRate = samplingRate; coreSamplingRate = samplingRate;
} }
...@@ -669,19 +692,6 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, ...@@ -669,19 +692,6 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
break; break;
} }
/* We need the frame length to call aacEncoder_LimitBitrate() */
hAacConfig->bitRate = aacEncoder_LimitBitrate(
NULL,
hAacConfig->sampleRate,
hAacConfig->framelength,
hAacConfig->nChannels,
hAacConfig->channelMode,
config->userBitrate,
hAacConfig->nSubFrames,
isSbrActive(hAacConfig),
hAacConfig->audioObjectType
);
switch ( hAacConfig->audioObjectType ) { switch ( hAacConfig->audioObjectType ) {
case AOT_ER_AAC_LD: case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
...@@ -699,24 +709,7 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, ...@@ -699,24 +709,7 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
break; break;
} }
if (hAacConfig->epConfig >= 0) { hAacConfig->bitRate = config->userBitrate;
hAacConfig->syntaxFlags |= AC_ER;
if (((INT)hAacConfig->channelMode < 1) || ((INT)hAacConfig->channelMode > 7)) {
return AACENC_INVALID_CONFIG; /* Cannel config 0 not supported. */
}
}
if ( FDKaacEnc_DetermineEncoderMode(&hAacConfig->channelMode, hAacConfig->nChannels) != AAC_ENC_OK) {
return AACENC_INVALID_CONFIG; /* nChannels doesn't match chMode, this is just a check-up */
}
if ( (hAacConfig->nChannels > hAacEncoder->nMaxAacChannels)
|| ( (FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannelsEff > hAacEncoder->nMaxSbrChannels) &&
isSbrActive(hAacConfig) )
)
{
return AACENC_INVALID_CONFIG; /* not enough channels allocated */
}
/* get bitrate in VBR configuration */ /* get bitrate in VBR configuration */
if ( (hAacConfig->bitrateMode>=1) && (hAacConfig->bitrateMode<=5) ) { if ( (hAacConfig->bitrateMode>=1) && (hAacConfig->bitrateMode<=5) ) {
...@@ -727,25 +720,52 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, ...@@ -727,25 +720,52 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
/* Set default bitrate if no external bitrate declared. */ /* Set default bitrate if no external bitrate declared. */
if (hAacConfig->bitRate==-1) { if ( (hAacConfig->bitrateMode==0) && (config->userBitrate==(UINT)-1) ) {
INT bitrate = FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannelsEff * hAacConfig->sampleRate; INT bitrate = FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannelsEff * hAacConfig->sampleRate;
switch (hAacConfig->audioObjectType)
if ( isPsActive(hAacConfig->audioObjectType) ) {
hAacConfig->bitRate = (bitrate>>1); /* 0.5 bit per sample */
}
else if ( isSbrActive(hAacConfig) )
{
if ( (config->userSbrRatio==2) || ((config->userSbrRatio==0)&&(hAacConfig->audioObjectType!=AOT_ER_AAC_ELD)) ) {
hAacConfig->bitRate = (bitrate + (bitrate>>2))>>1; /* 0.625 bits per sample */
}
if ( (config->userSbrRatio==1) || ((config->userSbrRatio==0)&&(hAacConfig->audioObjectType==AOT_ER_AAC_ELD)) ) {
hAacConfig->bitRate = (bitrate + (bitrate>>3)); /* 1.125 bits per sample */
}
} else
{ {
case AOT_AAC_LC:
hAacConfig->bitRate = bitrate + (bitrate>>1); /* 1.5 bits per sample */ hAacConfig->bitRate = bitrate + (bitrate>>1); /* 1.5 bits per sample */
break;
case AOT_SBR:
hAacConfig->bitRate = (bitrate + (bitrate>>2))>>1; /* 0.625 bits per sample */
break;
case AOT_PS:
hAacConfig->bitRate = (bitrate>>1); /* 0.5 bit per sample */
break;
default:
hAacConfig->bitRate = bitrate;
break;
} }
} }
/* Initialize SBR parameters */
if ( (config->userSbrRatio==0) && (isSbrActive(hAacConfig)) ) {
/* Automatic SBR ratio configuration
* - downsampled SBR for ELD
* - otherwise always dualrate SBR
*/
hAacConfig->sbrRatio = (hAacConfig->audioObjectType==AOT_ER_AAC_ELD) ? 1 : 2;
}
else {
/* SBR ratio has been set by the user, so use it. */
hAacConfig->sbrRatio = config->userSbrRatio;
}
/* We need the frame length to call aacEncoder_LimitBitrate() */
hAacConfig->bitRate = aacEncoder_LimitBitrate(
NULL,
hAacConfig->sampleRate,
hAacConfig->framelength,
hAacConfig->nChannels,
hAacConfig->channelMode,
hAacConfig->bitRate,
hAacConfig->nSubFrames,
isSbrActive(hAacConfig),
hAacConfig->sbrRatio,
hAacConfig->audioObjectType
);
/* Configure PNS */ /* Configure PNS */
if ( ((hAacConfig->bitrateMode>=1) && (hAacConfig->bitrateMode<=5)) /* VBR without PNS. */ if ( ((hAacConfig->bitrateMode>=1) && (hAacConfig->bitrateMode<=5)) /* VBR without PNS. */
|| (hAacConfig->useTns == 0) ) /* TNS required. */ || (hAacConfig->useTns == 0) ) /* TNS required. */
...@@ -753,6 +773,25 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, ...@@ -753,6 +773,25 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
hAacConfig->usePns = 0; hAacConfig->usePns = 0;
} }
if (hAacConfig->epConfig >= 0) {
hAacConfig->syntaxFlags |= AC_ER;
if (((INT)hAacConfig->channelMode < 1) || ((INT)hAacConfig->channelMode > 7)) {
return AACENC_INVALID_CONFIG; /* Cannel config 0 not supported. */
}
}
if ( FDKaacEnc_DetermineEncoderMode(&hAacConfig->channelMode, hAacConfig->nChannels) != AAC_ENC_OK) {
return AACENC_INVALID_CONFIG; /* nChannels doesn't match chMode, this is just a check-up */
}
if ( (hAacConfig->nChannels > hAacEncoder->nMaxAacChannels)
|| ( (FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannelsEff > hAacEncoder->nMaxSbrChannels) &&
isSbrActive(hAacConfig) )
)
{
return AACENC_INVALID_CONFIG; /* not enough channels allocated */
}
/* Meta data restriction. */ /* Meta data restriction. */
switch (hAacConfig->audioObjectType) switch (hAacConfig->audioObjectType)
{ {
...@@ -846,8 +885,6 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ...@@ -846,8 +885,6 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
SBR_ELEMENT_INFO sbrElInfo[(6)]; SBR_ELEMENT_INFO sbrElInfo[(6)];
CHANNEL_MAPPING channelMapping; CHANNEL_MAPPING channelMapping;
AUDIO_OBJECT_TYPE aot = hAacConfig->audioObjectType;
if ( FDKaacEnc_InitChannelMapping(hAacConfig->channelMode, if ( FDKaacEnc_InitChannelMapping(hAacConfig->channelMode,
hAacConfig->channelOrder, hAacConfig->channelOrder,
&channelMapping) != AAC_ENC_OK ) &channelMapping) != AAC_ENC_OK )
...@@ -875,8 +912,9 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ...@@ -875,8 +912,9 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
&aacBufferOffset, &aacBufferOffset,
&hAacConfig->nChannels, &hAacConfig->nChannels,
&hAacConfig->sampleRate, &hAacConfig->sampleRate,
&hAacConfig->sbrRatio,
&frameLength, &frameLength,
&hAacConfig->audioObjectType, hAacConfig->audioObjectType,
&hAacEncoder->nDelay, &hAacEncoder->nDelay,
(hAacConfig->audioObjectType == AOT_ER_AAC_ELD) ? 1 : TRANS_FAC, (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) ? 1 : TRANS_FAC,
(config->userTpHeaderPeriod!=0xFF) ? config->userTpHeaderPeriod : DEFAULT_HEADER_PERIOD_REPETITION_RATE, (config->userTpHeaderPeriod!=0xFF) ? config->userTpHeaderPeriod : DEFAULT_HEADER_PERIOD_REPETITION_RATE,
...@@ -884,7 +922,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ...@@ -884,7 +922,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
); );
/* Suppress AOT reconfiguration and check error status. */ /* Suppress AOT reconfiguration and check error status. */
if ( sbrError || (hAacConfig->audioObjectType!=aot) ) { if (sbrError) {
return AACENC_INIT_SBR_ERROR; return AACENC_INIT_SBR_ERROR;
} }
...@@ -953,7 +991,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ...@@ -953,7 +991,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
INT inputDataDelay = DELAY_AAC(hAacConfig->framelength); INT inputDataDelay = DELAY_AAC(hAacConfig->framelength);
if ( isSbrActive(hAacConfig) && hSbrEncoder!=NULL) { if ( isSbrActive(hAacConfig) && hSbrEncoder!=NULL) {
inputDataDelay = 2*inputDataDelay + sbrEncoder_GetInputDataDelay(*hSbrEncoder); inputDataDelay = hAacConfig->sbrRatio*inputDataDelay + sbrEncoder_GetInputDataDelay(*hSbrEncoder);
} }
if ( FDK_MetadataEnc_Init(hAacEncoder->hMetadataEnc, if ( FDK_MetadataEnc_Init(hAacEncoder->hMetadataEnc,
...@@ -1684,6 +1722,16 @@ AACENC_ERROR aacEncoder_SetParam( ...@@ -1684,6 +1722,16 @@ AACENC_ERROR aacEncoder_SetParam(
} }
} }
break; break;
case AACENC_SBR_RATIO:
if (settings->userSbrRatio != value) {
if (! ((value==0) || (value==1) || (value==2)) ) {
err = AACENC_INVALID_CONFIG;
break;
}
settings->userSbrRatio = value;
hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
}
break;
case AACENC_SBR_MODE: case AACENC_SBR_MODE:
if (settings->userSbrEnabled != value) { if (settings->userSbrEnabled != value) {
settings->userSbrEnabled = value; settings->userSbrEnabled = value;
...@@ -1805,7 +1853,7 @@ UINT aacEncoder_GetParam( ...@@ -1805,7 +1853,7 @@ UINT aacEncoder_GetParam(
value = (UINT)hAacEncoder->aacConfig.bitrateMode; value = (UINT)hAacEncoder->aacConfig.bitrateMode;
break; break;
case AACENC_SAMPLERATE: case AACENC_SAMPLERATE:
value = (UINT)settings->userSamplerate; value = (UINT)hAacEncoder->coderConfig.extSamplingRate;
break; break;
case AACENC_CHANNELMODE: case AACENC_CHANNELMODE:
value = (UINT)hAacEncoder->aacConfig.channelMode; value = (UINT)hAacEncoder->aacConfig.channelMode;
...@@ -1822,6 +1870,9 @@ UINT aacEncoder_GetParam( ...@@ -1822,6 +1870,9 @@ UINT aacEncoder_GetParam(
case AACENC_GRANULE_LENGTH: case AACENC_GRANULE_LENGTH:
value = (UINT)hAacEncoder->aacConfig.framelength; value = (UINT)hAacEncoder->aacConfig.framelength;
break; break;
case AACENC_SBR_RATIO:
value = isSbrActive(&hAacEncoder->aacConfig) ? hAacEncoder->aacConfig.sbrRatio : 0;
break;
case AACENC_SBR_MODE: case AACENC_SBR_MODE:
value = (UINT) (hAacEncoder->aacConfig.syntaxFlags & AC_SBR_PRESENT) ? 1 : 0; value = (UINT) (hAacEncoder->aacConfig.syntaxFlags & AC_SBR_PRESENT) ? 1 : 0;
break; break;
......
...@@ -101,6 +101,14 @@ amm-info@iis.fraunhofer.de ...@@ -101,6 +101,14 @@ amm-info@iis.fraunhofer.de
#define MAX_CODEC_FRAME_RATIO 2 #define MAX_CODEC_FRAME_RATIO 2
#define MAX_PAYLOAD_SIZE 256 #define MAX_PAYLOAD_SIZE 256
typedef enum codecType
{
CODEC_AAC=0,
CODEC_AACLD=1,
CODEC_UNSPECIFIED=99
} CODEC_TYPE;
typedef struct typedef struct
{ {
INT bitRate; INT bitRate;
...@@ -129,10 +137,11 @@ enum ...@@ -129,10 +137,11 @@ enum
typedef struct typedef struct
{ {
CODEC_TYPE coreCoder; /*!< LC or ELD */
UINT bitrateFrom; /*!< inclusive */ UINT bitrateFrom; /*!< inclusive */
UINT bitrateTo; /*!< exclusive */ UINT bitrateTo; /*!< exclusive */
USHORT sampleRate; /*!< */ UINT sampleRate; /*!< */
UCHAR numChannels; /*!< */ UCHAR numChannels; /*!< */
UCHAR startFreq; /*!< bs_start_freq */ UCHAR startFreq; /*!< bs_start_freq */
...@@ -158,6 +167,7 @@ typedef struct sbrConfiguration ...@@ -158,6 +167,7 @@ typedef struct sbrConfiguration
INT crcSbr; /*!< Flag: usage of SBR-CRC. */ INT crcSbr; /*!< Flag: usage of SBR-CRC. */
INT dynBwSupported; /*!< Flag: support for dynamic bandwidth in this combination. */ INT dynBwSupported; /*!< Flag: support for dynamic bandwidth in this combination. */
INT parametricCoding; /*!< Flag: usage of parametric coding tool. */ INT parametricCoding; /*!< Flag: usage of parametric coding tool. */
INT downSampleFactor; /*!< Sampling rate relation between the SBR and the core encoder. */
int freq_res_fixfix[3]; /*!< Frequency resolution of envelopes in frame class FIXFIX int freq_res_fixfix[3]; /*!< Frequency resolution of envelopes in frame class FIXFIX
0=1 Env; 1=2 Env; 2=4 Env; */ 0=1 Env; 1=2 Env; 2=4 Env; */
/* /*
...@@ -194,7 +204,6 @@ typedef struct sbrConfiguration ...@@ -194,7 +204,6 @@ typedef struct sbrConfiguration
INT useSaPan; /*!< Flag: usage of SAPAN stereo. */ INT useSaPan; /*!< Flag: usage of SAPAN stereo. */
INT dynBwEnabled; /*!< Flag: usage of dynamic bandwidth. */ INT dynBwEnabled; /*!< Flag: usage of dynamic bandwidth. */
INT bParametricStereo; /*!< Flag: usage of parametric stereo coding tool. */ INT bParametricStereo; /*!< Flag: usage of parametric stereo coding tool. */
INT bDownSampledSbr; /*!< Signal downsampled SBR is used. */
/* /*
header_extra1 configuration header_extra1 configuration
...@@ -214,7 +223,7 @@ typedef struct sbrConfiguration ...@@ -214,7 +223,7 @@ typedef struct sbrConfiguration
UCHAR init_amp_res_FF; UCHAR init_amp_res_FF;
} sbrConfiguration, *sbrConfigurationPtr ; } sbrConfiguration, *sbrConfigurationPtr ;
typedef struct typedef struct SBR_CONFIG_DATA
{ {
UINT sbrSyntaxFlags; /**< SBR syntax flags derived from AOT. */ UINT sbrSyntaxFlags; /**< SBR syntax flags derived from AOT. */
INT nChannels; /**< Number of channels. */ INT nChannels; /**< Number of channels. */
...@@ -240,9 +249,7 @@ typedef struct ...@@ -240,9 +249,7 @@ typedef struct
INT xposCtrlSwitch; /**< Flag indicates whether to switch xpos ctrl on the fly. */ INT xposCtrlSwitch; /**< Flag indicates whether to switch xpos ctrl on the fly. */
INT switchTransposers; /**< Flag indicates whether to switch xpos on the fly . */ INT switchTransposers; /**< Flag indicates whether to switch xpos on the fly . */
UCHAR initAmpResFF; UCHAR initAmpResFF;
} SBR_CONFIG_DATA; } SBR_CONFIG_DATA, *HANDLE_SBR_CONFIG_DATA;
typedef SBR_CONFIG_DATA *HANDLE_SBR_CONFIG_DATA;
typedef struct { typedef struct {
MP4_ELEMENT_ID elType; MP4_ELEMENT_ID elType;
...@@ -275,15 +282,26 @@ INT sbrEncoder_Open( ...@@ -275,15 +282,26 @@ INT sbrEncoder_Open(
); );
/** /**
* \brief get closest working bit rate to specified desired bit rate for a single SBR element * \brief Get closest working bitrate to specified desired
* \param bitRate the desired target bit rate * bitrate for a single SBR element.
* \param numChannels the amount of audio channels * \param bitRate The desired target bit rate
* \param coreSampleRate the sample rate of the core coder * \param numChannels The amount of audio channels
* \param the current Audio Object Type * \param coreSampleRate The sample rate of the core coder
* \return closest working bit rate to bitRate value * \param aot The current Audio Object Type
* \return Closest working bit rate to bitRate value
*/ */
UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate, AUDIO_OBJECT_TYPE aot); UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate, AUDIO_OBJECT_TYPE aot);
/**
* \brief Check whether downsampled SBR single rate is possible
* with given audio object type.
* \param aot The Audio object type.
* \return 0 when downsampled SBR is not possible,
* 1 when downsampled SBR is possible.
*/
UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot);
/** /**
* \brief Initialize SBR Encoder instance. * \brief Initialize SBR Encoder instance.
* \param phSbrEncoder Pointer to a SBR Encoder instance. * \param phSbrEncoder Pointer to a SBR Encoder instance.
...@@ -294,6 +312,7 @@ UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate ...@@ -294,6 +312,7 @@ UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate
* \param bufferOffset Returns the offset for the audio input data in order to do delay balancing. * \param bufferOffset Returns the offset for the audio input data in order to do delay balancing.
* \param numChannels Input: Encoder input channels. output: core encoder channels. * \param numChannels Input: Encoder input channels. output: core encoder channels.
* \param sampleRate Input: Encoder samplerate. output core encoder samplerate. * \param sampleRate Input: Encoder samplerate. output core encoder samplerate.
* \param downSampleFactor Input: Relation between SBR and core coder sampling rate;
* \param frameLength Input: Encoder frameLength. output core encoder frameLength. * \param frameLength Input: Encoder frameLength. output core encoder frameLength.
* \param aot Input: Desired AOT. output AOT to be used after parameter checking. * \param aot Input: Desired AOT. output AOT to be used after parameter checking.
* \param delay Input: core encoder delay. Output: total delay because of SBR. * \param delay Input: core encoder delay. Output: total delay because of SBR.
...@@ -303,21 +322,23 @@ UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate ...@@ -303,21 +322,23 @@ UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate
* - (1-10) corresponds to header repetition rate in frames. * - (1-10) corresponds to header repetition rate in frames.
* \return 0 on success, and non-zero if failed. * \return 0 on success, and non-zero if failed.
*/ */
INT sbrEncoder_Init( HANDLE_SBR_ENCODER hSbrEncoder, INT sbrEncoder_Init(
SBR_ELEMENT_INFO elInfo[(6)], HANDLE_SBR_ENCODER hSbrEncoder,
int noElements, SBR_ELEMENT_INFO elInfo[(6)],
INT_PCM *inputBuffer, int noElements,
INT *bandwidth, INT_PCM *inputBuffer,
INT *bufferOffset, INT *coreBandwidth,
INT *numChannels, INT *inputBufferOffset,
INT *sampleRate, INT *numChannels,
INT *frameLength, INT *sampleRate,
AUDIO_OBJECT_TYPE *aot, UINT *downSampleFactor,
int *delay, INT *frameLength,
int transformFactor, AUDIO_OBJECT_TYPE aot,
const int headerPeriod, int *delay,
ULONG statesInitFlag int transformFactor,
); const int headerPeriod,
ULONG statesInitFlag
);
/** /**
* \brief Do delay line buffers housekeeping. To be called after each encoded audio frame. * \brief Do delay line buffers housekeeping. To be called after each encoded audio frame.
...@@ -360,7 +381,7 @@ INT sbrEncoder_EncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, ...@@ -360,7 +381,7 @@ INT sbrEncoder_EncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
* \param fSendHeaders Flag indicating that the SBR encoder should send more headers in the SBR payload or not. * \param fSendHeaders Flag indicating that the SBR encoder should send more headers in the SBR payload or not.
* \return void * \return void
*/ */
void sbrEncoder_GetHeader(SBR_ENCODER *sbrEncoder, void sbrEncoder_GetHeader(HANDLE_SBR_ENCODER sbrEncoder,
HANDLE_FDK_BITSTREAM hBs, HANDLE_FDK_BITSTREAM hBs,
INT element_index, INT element_index,
int fSendHeaders); int fSendHeaders);
......
...@@ -124,11 +124,6 @@ struct SBR_HEADER_DATA ...@@ -124,11 +124,6 @@ struct SBR_HEADER_DATA
INT alterScale; INT alterScale;
INT freqScale; INT freqScale;
/*
element of sbrdata
*/
SR_MODE sampleRateMode;
/* /*
element of channelpairelement element of channelpairelement
*/ */
......
...@@ -129,9 +129,6 @@ FDKsbrEnc_getEnergyFromCplxQmfData(FIXP_DBL **RESTRICT energyValues,/*!< the res ...@@ -129,9 +129,6 @@ FDKsbrEnc_getEnergyFromCplxQmfData(FIXP_DBL **RESTRICT energyValues,/*!< the res
/* Get Scratch buffer */ /* Get Scratch buffer */
C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, QMF_CHANNELS*QMF_MAX_TIME_SLOTS/2); C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, QMF_CHANNELS*QMF_MAX_TIME_SLOTS/2);
FDK_ASSERT(numberBands <= QMF_CHANNELS);
FDK_ASSERT(numberCols <= QMF_MAX_TIME_SLOTS);
/* Get max possible scaling of QMF data */ /* Get max possible scaling of QMF data */
scale = DFRACT_BITS; scale = DFRACT_BITS;
for (k=0; k<numberCols; k++) { for (k=0; k<numberCols; k++) {
......
...@@ -1244,25 +1244,38 @@ FDKsbrEnc_InitSbrMissingHarmonicsDetector ( ...@@ -1244,25 +1244,38 @@ FDKsbrEnc_InitSbrMissingHarmonicsDetector (
FDK_ASSERT(totNoEst <= MAX_NO_OF_ESTIMATES); FDK_ASSERT(totNoEst <= MAX_NO_OF_ESTIMATES);
switch(frameSize){ if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
case 2048: {
hs->transientPosOffset = FRAME_MIDDLE_SLOT_2048; switch(frameSize){
hs->timeSlots = NUMBER_TIME_SLOTS_2048; case 1024:
break; case 512:
case 1920: hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
hs->transientPosOffset = FRAME_MIDDLE_SLOT_1920; hs->timeSlots = 16;
hs->timeSlots = NUMBER_TIME_SLOTS_1920; break;
break; case 960:
case 1024: case 480:
hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
hs->timeSlots = 16; hs->timeSlots = 15;
break; break;
case 960: default:
hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; return -1;
hs->timeSlots = 15; }
break; } else
default: {
return -1; switch(frameSize){
case 2048:
case 1024:
hs->transientPosOffset = FRAME_MIDDLE_SLOT_2048;
hs->timeSlots = NUMBER_TIME_SLOTS_2048;
break;
case 1920:
case 960:
hs->transientPosOffset = FRAME_MIDDLE_SLOT_1920;
hs->timeSlots = NUMBER_TIME_SLOTS_1920;
break;
default:
return -1;
}
} }
if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
......
...@@ -102,7 +102,7 @@ static const FIXP_DBL QuantOffset = (INT)0xfc000000; /* ld64(0.25) */ ...@@ -102,7 +102,7 @@ static const FIXP_DBL QuantOffset = (INT)0xfc000000; /* ld64(0.25) */
#define max(a,b) ( a > b ? a:b) #define max(a,b) ( a > b ? a:b)
#endif #endif
#define NOISE_FLOOR_OFFSET_SCALING (3) #define NOISE_FLOOR_OFFSET_SCALING (4)
...@@ -484,11 +484,13 @@ FDKsbrEnc_InitSbrNoiseFloorEstimate (HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoise ...@@ -484,11 +484,13 @@ FDKsbrEnc_InitSbrNoiseFloorEstimate (HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoise
tmp = ((FIXP_DBL)MAXVAL_DBL)>>NOISE_FLOOR_OFFSET_SCALING; tmp = ((FIXP_DBL)MAXVAL_DBL)>>NOISE_FLOOR_OFFSET_SCALING;
} }
else { else {
FDK_ASSERT(noiseFloorOffset<=8); /* because of NOISE_FLOOR_OFFSET_SCALING */ /* noiseFloorOffset has to be smaller than 12, because
the result of the calculation below must be smaller than 1:
(2^(noiseFloorOffset/3))*2^4<1 */
FDK_ASSERT(noiseFloorOffset<12);
/* Assumes the noise floor offset in tuning table are in q31 */ /* Assumes the noise floor offset in tuning table are in q31 */
/* Currently the table contains only 0 for noise floor offset */ /* Change the qformat here when non-zero values would be filled */
/* Change the qformat here when non-zero values would be filled */
exp = fDivNorm((FIXP_DBL)noiseFloorOffset, 3, &qexp); exp = fDivNorm((FIXP_DBL)noiseFloorOffset, 3, &qexp);
tmp = fPow(2, DFRACT_BITS-1, exp, qexp, &qtmp); tmp = fPow(2, DFRACT_BITS-1, exp, qexp, &qtmp);
tmp = scaleValue(tmp, qtmp-NOISE_FLOOR_OFFSET_SCALING); tmp = scaleValue(tmp, qtmp-NOISE_FLOOR_OFFSET_SCALING);
...@@ -527,24 +529,30 @@ FDKsbrEnc_resetSbrNoiseFloorEstimate (HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoise ...@@ -527,24 +529,30 @@ FDKsbrEnc_resetSbrNoiseFloorEstimate (HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoise
h_sbrNoiseFloorEstimate->noNoiseBands = 1; h_sbrNoiseFloorEstimate->noNoiseBands = 1;
} }
else{ else{
/* /*
* Calculate number of noise bands 1,2 or 3 bands/octave * Calculate number of noise bands 1,2 or 3 bands/octave
********************************************************/ ********************************************************/
FIXP_DBL tmp, ratio, lg2; FIXP_DBL tmp, ratio, lg2;
INT ratio_e, qlg2; INT ratio_e, qlg2, nNoiseBands;
ratio = fDivNorm(k2, kx, &ratio_e); ratio = fDivNorm(k2, kx, &ratio_e);
lg2 = fLog2(ratio, ratio_e, &qlg2); lg2 = fLog2(ratio, ratio_e, &qlg2);
tmp = fMult((FIXP_DBL)(h_sbrNoiseFloorEstimate->noiseBands<<24), lg2); tmp = fMult((FIXP_DBL)(h_sbrNoiseFloorEstimate->noiseBands<<24), lg2);
tmp = scaleValue(tmp, qlg2-23); tmp = scaleValue(tmp, qlg2-23);
h_sbrNoiseFloorEstimate->noNoiseBands = (INT)((tmp + (FIXP_DBL)1) >> 1); nNoiseBands = (INT)((tmp + (FIXP_DBL)1) >> 1);
if (nNoiseBands > MAX_NUM_NOISE_COEFFS ) {
nNoiseBands = MAX_NUM_NOISE_COEFFS;
}
if( nNoiseBands == 0 ) {
nNoiseBands = 1;
}
if (h_sbrNoiseFloorEstimate->noNoiseBands > MAX_NUM_NOISE_COEFFS) h_sbrNoiseFloorEstimate->noNoiseBands = nNoiseBands;
h_sbrNoiseFloorEstimate->noNoiseBands = MAX_NUM_NOISE_COEFFS;
if( h_sbrNoiseFloorEstimate->noNoiseBands==0)
h_sbrNoiseFloorEstimate->noNoiseBands=1;
} }
......
...@@ -315,7 +315,7 @@ static FDK_PSENC_ERROR DownmixPSQmfData( ...@@ -315,7 +315,7 @@ static FDK_PSENC_ERROR DownmixPSQmfData(
} }
else { else {
int n, k; int n, k;
C_ALLOC_SCRATCH_START(pWorkBuffer, FIXP_QMF, QMF_CHANNELS*2); C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_QMF, 2*QMF_CHANNELS)
/* define scalings */ /* define scalings */
int dynQmfScale = fixMax(0, hParametricStereo->dmxScale-1); /* scale one bit more for addition of left and right */ int dynQmfScale = fixMax(0, hParametricStereo->dmxScale-1); /* scale one bit more for addition of left and right */
...@@ -400,8 +400,7 @@ static FDK_PSENC_ERROR DownmixPSQmfData( ...@@ -400,8 +400,7 @@ static FDK_PSENC_ERROR DownmixPSQmfData(
*qmfScale = -downmixScale + 7; *qmfScale = -downmixScale + 7;
C_ALLOC_SCRATCH_END(pWorkBuffer, FIXP_QMF, QMF_CHANNELS*2); C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_QMF, 2*QMF_CHANNELS)
{ {
const INT noQmfSlots2 = hParametricStereo->noQmfSlots>>1; const INT noQmfSlots2 = hParametricStereo->noQmfSlots>>1;
...@@ -475,10 +474,9 @@ FDK_PSENC_ERROR FDKsbrEnc_PSEnc_ParametricStereoProcessing( ...@@ -475,10 +474,9 @@ FDK_PSENC_ERROR FDKsbrEnc_PSEnc_ParametricStereoProcessing(
) )
{ {
FDK_PSENC_ERROR error = PSENC_OK; FDK_PSENC_ERROR error = PSENC_OK;
INT noQmfBands = hParametricStereo->noQmfBands;
INT psQmfScale[MAX_PS_CHANNELS] = {0}; INT psQmfScale[MAX_PS_CHANNELS] = {0};
int psCh, i; int psCh, i;
C_ALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, QMF_CHANNELS*4); C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_QMF, 4*QMF_CHANNELS)
for (psCh = 0; psCh<MAX_PS_CHANNELS; psCh ++) { for (psCh = 0; psCh<MAX_PS_CHANNELS; psCh ++) {
...@@ -507,7 +505,7 @@ FDK_PSENC_ERROR FDKsbrEnc_PSEnc_ParametricStereoProcessing( ...@@ -507,7 +505,7 @@ FDK_PSENC_ERROR FDKsbrEnc_PSEnc_ParametricStereoProcessing(
} /* for psCh */ } /* for psCh */
C_ALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, QMF_CHANNELS*4); C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_QMF, 4*QMF_CHANNELS)
/* find best scaling in new QMF and Hybrid data */ /* find best scaling in new QMF and Hybrid data */
psFindBestScaling( hParametricStereo, psFindBestScaling( hParametricStereo,
......
...@@ -105,7 +105,8 @@ amm-info@iis.fraunhofer.de ...@@ -105,7 +105,8 @@ amm-info@iis.fraunhofer.de
/* SBR bitstream delay */ /* SBR bitstream delay */
#define DELAY_FRAMES 2 #define DELAY_FRAMES 2
typedef struct {
typedef struct SBR_CHANNEL {
struct ENV_CHANNEL hEnvChannel; struct ENV_CHANNEL hEnvChannel;
//INT_PCM *pDSOutBuffer; /**< Pointer to downsampled audio output of SBR encoder */ //INT_PCM *pDSOutBuffer; /**< Pointer to downsampled audio output of SBR encoder */
DOWNSAMPLER downSampler; DOWNSAMPLER downSampler;
...@@ -113,7 +114,7 @@ typedef struct { ...@@ -113,7 +114,7 @@ typedef struct {
} SBR_CHANNEL; } SBR_CHANNEL;
typedef SBR_CHANNEL* HANDLE_SBR_CHANNEL; typedef SBR_CHANNEL* HANDLE_SBR_CHANNEL;
typedef struct { typedef struct SBR_ELEMENT {
HANDLE_SBR_CHANNEL sbrChannel[2]; HANDLE_SBR_CHANNEL sbrChannel[2];
QMF_FILTER_BANK *hQmfAnalysis[2]; QMF_FILTER_BANK *hQmfAnalysis[2];
SBR_CONFIG_DATA sbrConfigData; SBR_CONFIG_DATA sbrConfigData;
...@@ -126,10 +127,9 @@ typedef struct { ...@@ -126,10 +127,9 @@ typedef struct {
UCHAR payloadDelayLine[1+DELAY_FRAMES][MAX_PAYLOAD_SIZE]; UCHAR payloadDelayLine[1+DELAY_FRAMES][MAX_PAYLOAD_SIZE];
UINT payloadDelayLineSize[1+DELAY_FRAMES]; /* Sizes in bits */ UINT payloadDelayLineSize[1+DELAY_FRAMES]; /* Sizes in bits */
} SBR_ELEMENT; } SBR_ELEMENT, *HANDLE_SBR_ELEMENT;
typedef SBR_ELEMENT* HANDLE_SBR_ELEMENT;
struct SBR_ENCODER typedef struct SBR_ENCODER
{ {
HANDLE_SBR_ELEMENT sbrElement[(6)]; HANDLE_SBR_ELEMENT sbrElement[(6)];
HANDLE_SBR_CHANNEL pSbrChannel[(6)]; HANDLE_SBR_CHANNEL pSbrChannel[(6)];
...@@ -142,6 +142,7 @@ struct SBR_ENCODER ...@@ -142,6 +142,7 @@ struct SBR_ENCODER
int bufferOffset; /* Offset for SBR parameter extraction in time domain input buffer. */ int bufferOffset; /* Offset for SBR parameter extraction in time domain input buffer. */
int downsampledOffset; /* Offset of downsampled/mixed output for core encoder. */ int downsampledOffset; /* Offset of downsampled/mixed output for core encoder. */
int downmixSize; /* Size in samples of downsampled/mixed output for core encoder. */ int downmixSize; /* Size in samples of downsampled/mixed output for core encoder. */
INT downSampleFactor; /* Sampling rate relation between the SBR and the core encoder. */
int fTimeDomainDownsampling; /* Flag signalling time domain downsampling instead of QMF downsampling. */ int fTimeDomainDownsampling; /* Flag signalling time domain downsampling instead of QMF downsampling. */
int nBitstrDelay; /* Amount of SBR frames to be delayed in bitstream domain. */ int nBitstrDelay; /* Amount of SBR frames to be delayed in bitstream domain. */
INT estimateBitrate; /* estimate bitrate of SBR encoder */ INT estimateBitrate; /* estimate bitrate of SBR encoder */
...@@ -158,7 +159,8 @@ struct SBR_ENCODER ...@@ -158,7 +159,8 @@ struct SBR_ENCODER
INT maxChannels; INT maxChannels;
INT supportPS; INT supportPS;
} ;
} SBR_ENCODER;
#endif /* __SBR_H */ #endif /* __SBR_H */
...@@ -268,13 +268,6 @@ typedef enum ...@@ -268,13 +268,6 @@ typedef enum
} }
INVF_MODE; INVF_MODE;
typedef enum
{
SINGLE_RATE,
DUAL_RATE
}
SR_MODE;
typedef enum typedef enum
{ {
FREQ_RES_LOW = 0, FREQ_RES_LOW = 0,
......
...@@ -83,7 +83,7 @@ amm-info@iis.fraunhofer.de ...@@ -83,7 +83,7 @@ amm-info@iis.fraunhofer.de
/*************************** Fraunhofer IIS FDK Tools *********************** /*************************** Fraunhofer IIS FDK Tools ***********************
Author(s): Andreas Ehret Author(s): Andreas Ehret, Tobias Chalupka
Description: SBR encoder top level processing. Description: SBR encoder top level processing.
******************************************************************************/ ******************************************************************************/
...@@ -103,7 +103,7 @@ amm-info@iis.fraunhofer.de ...@@ -103,7 +103,7 @@ amm-info@iis.fraunhofer.de
#define SBRENCODER_LIB_VL0 3 #define SBRENCODER_LIB_VL0 3
#define SBRENCODER_LIB_VL1 3 #define SBRENCODER_LIB_VL1 3
#define SBRENCODER_LIB_VL2 2 #define SBRENCODER_LIB_VL2 3
...@@ -119,34 +119,30 @@ amm-info@iis.fraunhofer.de ...@@ -119,34 +119,30 @@ amm-info@iis.fraunhofer.de
(core2sbr delay ) ds (read, core and ds area) (core2sbr delay ) ds (read, core and ds area)
*/ */
#define DOWN_SMPL_FAC (2) #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 SFL(fl) (fl*DOWN_SMPL_FAC) /* SBR frame length (hardcoded to downsample factor of 2) */ #define DELAY_QMF_ANA(dwnsmp) ((320<<((dwnsmp)-1)) - (32<<((dwnsmp)-1))) /* Full bandwidth */
#define STS(fl) (SFL(fl)/64) /* SBR Time Slots */ #define DELAY_HYB_ANA (10*64) /* + 0.5 */ /* */
#define DELAY_HYB_SYN (6*64 - 32) /* */
#define DELAY_QMF_ANA (640 - 64) /* Full bandwidth */ #define DELAY_QMF_POSTPROC(dwnsmp) (32*(dwnsmp)) /* QMF postprocessing delay */
#define DELAY_QMF_ANAELD (32) #define DELAY_DEC_QMF(dwnsmp) (6 * SFB(dwnsmp) ) /* Decoder QMF overlap */
#define DELAY_HYB_ANA (10*64) /* + 0.5 */ #define DELAY_QMF_SYN (2) /* NO_POLY/2=2.5, rounded down to 2 */
#define DELAY_HYB_SYN (6*64 - 32) #define DELAY_QMF_DS (32) /* QMF synthesis for downsampled time signal */
#define DELAY_QMF_SYNELD (32)
#define DELAY_DEC_QMF (6*64) /* Decoder QMF overlap */
#define DELAY_QMF_SYN (2) /* NO_POLY/2 */
#define DELAY_QMF_DS (32) /* QMF synthesis for downsampled time signal */
/* Delay in QMF paths */ /* Delay in QMF paths */
#define DELAY_SBR(fl) (DELAY_QMF_ANA + (64*STS(fl)-1) + DELAY_QMF_SYN) #define DELAY_SBR(fl,dwnsmp) (DELAY_QMF_ANA(dwnsmp) + (SFB(dwnsmp)*STS(fl) - 1) + DELAY_QMF_SYN)
#define DELAY_PS(fl) (DELAY_QMF_ANA + DELAY_HYB_ANA + DELAY_DEC_QMF + (64*STS(fl)-1) + DELAY_HYB_SYN + 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) (DELAY_QMF_ANAELD + (((fl)+((fl)/2))*2 - 1) + DELAY_QMF_SYNELD) #define DELAY_ELDSBR(fl,dwnsmp) ( ( ((fl)/2)*(dwnsmp) ) - 1 + DELAY_QMF_POSTPROC(dwnsmp) )
/* Delay differences for SBR and SBR+PS */ /* Delay differences for SBR and SBR+PS */
#define MAX_DS_FILTER_DELAY (34) /* the additional max downsampler filter delay (source fs) */ #define MAX_DS_FILTER_DELAY (5) /* the additional max downsampler filter delay (source fs) */
#define DELAY_AAC2SBR(fl) ((/*RESAMPLER +*/ /*(DELAY_AAC(fl)*2) + */ DELAY_QMF_ANA + DELAY_DEC_QMF + DELAY_QMF_SYN) - DELAY_SBR(fl)) /* 1537 */ #define DELAY_AAC2SBR(fl,dwnsmp) ((DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_QMF_SYN) - DELAY_SBR((fl),(dwnsmp)))
#define DELAY_ELD2SBR(fl) ((/*RESAMPLER +*/ /*(DELAY_ELD(fl)*2) + */ DELAY_QMF_ANAELD + DELAY_QMF_SYNELD) - DELAY_ELDSBR(fl)) #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 */
#define DELAY_AAC2PS(fl) ((DELAY_QMF_ANA + DELAY_QMF_DS + /*(DELAY_AAC(fl)*2)*/ + DELAY_QMF_ANA + DELAY_DEC_QMF + DELAY_HYB_SYN + DELAY_QMF_SYN) - DELAY_PS(fl)) /* 2048 - 463*2 */
/* Assumption: that the sample delay resulting of of DELAY_AAC2PS is always smaller than the sample delay implied by DELAY_AAC2SBR */ /* 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) + MAX_DS_FILTER_DELAY) #define MAX_SAMPLE_DELAY (DELAY_AAC2SBR(1024,2) + MAX_DS_FILTER_DELAY) /* maximum delay: frame length of 1024 and dual-rate sbr */
/***************************************************************************/ /***************************************************************************/
...@@ -172,41 +168,39 @@ getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */ ...@@ -172,41 +168,39 @@ getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */
UINT *pBitRateClosest UINT *pBitRateClosest
) )
{ {
int i, paramSetTop, bitRateClosestLowerIndex=-1, bitRateClosestUpperIndex=-1, found = 0; int i, bitRateClosestLowerIndex=-1, bitRateClosestUpperIndex=-1, found = 0;
UINT bitRateClosestUpper = 0, bitRateClosestLower=DISTANCE_CEIL_VALUE; UINT bitRateClosestUpper = 0, bitRateClosestLower=DISTANCE_CEIL_VALUE;
int isforThisCodec=0;
FDK_ASSERT(SBRENC_TUNING_SIZE == sizeof(sbrTuningTable)/sizeof(sbrTuningTable[0])); #define isForThisCore(i) \
( ( sbrTuningTable[i].coreCoder == CODEC_AACLD && core == AOT_ER_AAC_ELD ) || \
if (core == AOT_ER_AAC_ELD) { ( sbrTuningTable[i].coreCoder == CODEC_AAC && core != AOT_ER_AAC_ELD ) )
paramSetTop = SBRENC_TUNING_SIZE;
i = SBRENC_AACLC_TUNING_SIZE;
} else {
paramSetTop = SBRENC_AACLC_TUNING_SIZE;
i = 0;
}
for (; i < paramSetTop ; i++) { for (i=0; i < sbrTuningTableSize ; i++) {
if ( numChannels == sbrTuningTable [i].numChannels if ( isForThisCore(i) ) /* tuning table is for this core codec */
&& sampleRate == sbrTuningTable [i].sampleRate )
{ {
found = 1; if ( numChannels == sbrTuningTable [i].numChannels
if ((bitrate >= sbrTuningTable [i].bitrateFrom) && && sampleRate == sbrTuningTable [i].sampleRate )
(bitrate < sbrTuningTable [i].bitrateTo)) { {
bitRateClosestLower = bitrate; found = 1;
bitRateClosestUpper = bitrate; if ((bitrate >= sbrTuningTable [i].bitrateFrom) &&
//FDKprintf("entry %d\n", i); (bitrate < sbrTuningTable [i].bitrateTo)) {
return i ; bitRateClosestLower = bitrate;
} else { bitRateClosestUpper = bitrate;
if ( sbrTuningTable [i].bitrateFrom > bitrate ) { //FDKprintf("entry %d\n", i);
if (sbrTuningTable [i].bitrateFrom < bitRateClosestLower) { return i ;
bitRateClosestLower = sbrTuningTable [i].bitrateFrom; } else {
bitRateClosestLowerIndex = i; 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 <= bitrate ) { if (sbrTuningTable [i].bitrateTo > bitRateClosestUpper) {
if (sbrTuningTable [i].bitrateTo > bitRateClosestUpper) { bitRateClosestUpper = sbrTuningTable [i].bitrateTo-1;
bitRateClosestUpper = sbrTuningTable [i].bitrateTo-1; bitRateClosestUpperIndex = i;
bitRateClosestUpperIndex = i; }
} }
} }
} }
...@@ -215,7 +209,7 @@ getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */ ...@@ -215,7 +209,7 @@ getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */
if (pBitRateClosest != NULL) if (pBitRateClosest != NULL)
{ {
/* Is there was at least one matching tuning entry found then pick the least distance bit rate */ /* If there was at least one matching tuning entry found then pick the least distance bit rate */
if (found) if (found)
{ {
int distanceUpper=DISTANCE_CEIL_VALUE, distanceLower=DISTANCE_CEIL_VALUE; int distanceUpper=DISTANCE_CEIL_VALUE, distanceLower=DISTANCE_CEIL_VALUE;
...@@ -295,6 +289,52 @@ getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest){ ...@@ -295,6 +289,52 @@ getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest){
return INVALID_TABLE_IDX; return INVALID_TABLE_IDX;
} }
/***************************************************************************/
/*!
\brief In case of downsampled SBR we may need to lower the stop freq
of a tuning setting to fit into the lower half of the
spectrum ( which is sampleRate/4 )
\return the adapted stop frequency index (-1 -> error)
\ingroup SbrEncCfg
****************************************************************************/
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) {
stopFreq--;
}
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;
return stopFreq;
}
/***************************************************************************/ /***************************************************************************/
/*! /*!
...@@ -307,15 +347,16 @@ getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest){ ...@@ -307,15 +347,16 @@ getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest){
****************************************************************************/ ****************************************************************************/
static UINT static UINT
FDKsbrEnc_IsSbrSettingAvail (UINT bitrate, /*! the total bitrate in bits/sec */ FDKsbrEnc_IsSbrSettingAvail (
UINT vbrMode, /*! the vbr paramter, 0 means constant bitrate */ UINT bitrate, /*! the total bitrate in bits/sec */
UINT numOutputChannels,/*! the number of channels for the core coder */ UINT vbrMode, /*! the vbr paramter, 0 means constant bitrate */
UINT sampleRateInput, /*! the input sample rate [in Hz] */ UINT numOutputChannels, /*! the number of channels for the core coder */
AUDIO_OBJECT_TYPE core UINT sampleRateInput, /*! the input sample rate [in Hz] */
) UINT sampleRateCore, /*! the core's sampling rate */
AUDIO_OBJECT_TYPE core
)
{ {
INT idx = INVALID_TABLE_IDX; INT idx = INVALID_TABLE_IDX;
UINT sampleRateCore;
if (sampleRateInput < 16000) if (sampleRateInput < 16000)
return 0; return 0;
...@@ -335,8 +376,6 @@ FDKsbrEnc_IsSbrSettingAvail (UINT bitrate, /*! the total bitrate in bit ...@@ -335,8 +376,6 @@ FDKsbrEnc_IsSbrSettingAvail (UINT bitrate, /*! the total bitrate in bit
bitrate *= numOutputChannels; bitrate *= numOutputChannels;
} }
/* try DOWN_SMPL_FAC of the input sampling rate */
sampleRateCore = sampleRateInput/DOWN_SMPL_FAC;
idx = getSbrTuningTableIndex(bitrate, numOutputChannels, sampleRateCore, core, NULL); idx = getSbrTuningTableIndex(bitrate, numOutputChannels, sampleRateCore, core, NULL);
return (idx == INVALID_TABLE_IDX ? 0 : 1); return (idx == INVALID_TABLE_IDX ? 0 : 1);
...@@ -356,7 +395,8 @@ static UINT ...@@ -356,7 +395,8 @@ static UINT
FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modified */ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modified */
UINT bitRate, /*! the total bitrate in bits/sec */ UINT bitRate, /*! the total bitrate in bits/sec */
UINT numChannels, /*! the core coder number of channels */ UINT numChannels, /*! the core coder number of channels */
UINT fsCore, /*! the core coder sampling rate in Hz */ 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 transFac, /*! the short block to long block ratio */
UINT standardBitrate, /*! the standard bitrate per channel in bits/sec */ UINT standardBitrate, /*! the standard bitrate per channel in bits/sec */
UINT vbrMode, /*! the vbr paramter, 0 poor quality .. 100 high quality*/ UINT vbrMode, /*! the vbr paramter, 0 poor quality .. 100 high quality*/
...@@ -366,15 +406,12 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif ...@@ -366,15 +406,12 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
AUDIO_OBJECT_TYPE core) /* Core audio codec object type */ AUDIO_OBJECT_TYPE core) /* Core audio codec object type */
{ {
INT idx = INVALID_TABLE_IDX; INT idx = INVALID_TABLE_IDX;
UINT sampleRate; /* set the core codec settings */
/* set the codec settings */
config->codecSettings.bitRate = bitRate; config->codecSettings.bitRate = bitRate;
config->codecSettings.nChannels = numChannels; config->codecSettings.nChannels = numChannels;
config->codecSettings.sampleFreq = fsCore; config->codecSettings.sampleFreq = sampleRateCore;
config->codecSettings.transFac = transFac; config->codecSettings.transFac = transFac;
config->codecSettings.standardBitrate = standardBitrate; config->codecSettings.standardBitrate = standardBitrate;
sampleRate = fsCore * DOWN_SMPL_FAC;
if (bitRate==0) { if (bitRate==0) {
/* map vbr quality to bitrate */ /* map vbr quality to bitrate */
...@@ -391,13 +428,13 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif ...@@ -391,13 +428,13 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
bitRate *= numChannels; bitRate *= numChannels;
/* fix to enable mono vbrMode<40 @ 44.1 of 48kHz */ /* fix to enable mono vbrMode<40 @ 44.1 of 48kHz */
if (numChannels==1) { if (numChannels==1) {
if (sampleRate==44100 || sampleRate==48000) { if (sampleRateSbr==44100 || sampleRateSbr==48000) {
if (vbrMode<40) bitRate = 32000; if (vbrMode<40) bitRate = 32000;
} }
} }
} }
idx = getSbrTuningTableIndex(bitRate,numChannels,fsCore, core, NULL); idx = getSbrTuningTableIndex(bitRate,numChannels,sampleRateCore, core, NULL);
if (idx != INVALID_TABLE_IDX) { if (idx != INVALID_TABLE_IDX) {
config->startFreq = sbrTuningTable[idx].startFreq ; config->startFreq = sbrTuningTable[idx].startFreq ;
...@@ -407,6 +444,21 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif ...@@ -407,6 +444,21 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
config->stopFreq = sbrTuningTable[idx].stopFreqSpeech; 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
);
if (dsStopFreq < 0) {
return 0;
}
config->stopFreq = dsStopFreq;
}
config->sbr_noise_bands = sbrTuningTable[idx].numNoiseBands ; config->sbr_noise_bands = sbrTuningTable[idx].numNoiseBands ;
if (core == AOT_ER_AAC_ELD) if (core == AOT_ER_AAC_ELD)
config->init_amp_res_FF = SBR_AMP_RES_1_5; config->init_amp_res_FF = SBR_AMP_RES_1_5;
...@@ -455,19 +507,20 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif ...@@ -455,19 +507,20 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
description: initializes the SBR confifuration description: initializes the SBR confifuration
returns: error status returns: error status
input: - core codec type, input: - core codec type,
- fac of SBR to core frame length, - factor of SBR to core frame length,
- core frame length - core frame length
output: initialized SBR configuration output: initialized SBR configuration
*****************************************************************************/ *****************************************************************************/
static UINT static UINT
FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config, FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
INT coreSbrFrameLenFac, INT downSampleFactor,
UINT codecGranuleLen) UINT codecGranuleLen
)
{ {
if ( (coreSbrFrameLenFac != 2) || if ( (downSampleFactor < 1 || downSampleFactor > 2) ||
(codecGranuleLen*coreSbrFrameLenFac > QMF_CHANNELS*QMF_MAX_TIME_SLOTS) ) (codecGranuleLen*downSampleFactor > QMF_CHANNELS*QMF_MAX_TIME_SLOTS) )
return(1); return(0); /* error */
config->SendHeaderDataTime = 1000; config->SendHeaderDataTime = 1000;
config->useWaveCoding = 0; config->useWaveCoding = 0;
...@@ -476,8 +529,8 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config, ...@@ -476,8 +529,8 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
config->tran_thr = 13000; config->tran_thr = 13000;
config->parametricCoding = 1; config->parametricCoding = 1;
config->sbrFrameSize = codecGranuleLen * coreSbrFrameLenFac; config->sbrFrameSize = codecGranuleLen * downSampleFactor;
config->downSampleFactor = downSampleFactor;
/* sbr default parameters */ /* sbr default parameters */
config->sbr_data_extra = 0; config->sbr_data_extra = 0;
...@@ -497,7 +550,6 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config, ...@@ -497,7 +550,6 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
config->sbr_xpos_level = 0; config->sbr_xpos_level = 0;
config->useSaPan = 0; config->useSaPan = 0;
config->dynBwEnabled = 0; config->dynBwEnabled = 0;
config->bDownSampledSbr = 0;
/* the following parameters are overwritten by the FDKsbrEnc_AdjustSbrSettings() function since /* the following parameters are overwritten by the FDKsbrEnc_AdjustSbrSettings() function since
...@@ -645,46 +697,62 @@ void sbrEncoder_Close (HANDLE_SBR_ENCODER *phSbrEncoder) ...@@ -645,46 +697,62 @@ void sbrEncoder_Close (HANDLE_SBR_ENCODER *phSbrEncoder)
output: error info output: error info
*****************************************************************************/ *****************************************************************************/
static INT updateFreqBandTable(HANDLE_SBR_CONFIG_DATA sbrConfigData, static INT updateFreqBandTable(
HANDLE_SBR_HEADER_DATA sbrHeaderData, HANDLE_SBR_CONFIG_DATA sbrConfigData,
INT noQmfChannels) HANDLE_SBR_HEADER_DATA sbrHeaderData,
const INT downSampleFactor
)
{ {
INT k0, k2; INT k0, k2;
if(FDKsbrEnc_FindStartAndStopBand(sbrConfigData->sampleFreq, if( FDKsbrEnc_FindStartAndStopBand (
noQmfChannels, sbrConfigData->sampleFreq,
sbrHeaderData->sbr_start_frequency, sbrConfigData->sampleFreq >> (downSampleFactor-1),
sbrHeaderData->sbr_stop_frequency, sbrConfigData->noQmfBands,
sbrHeaderData->sampleRateMode, sbrHeaderData->sbr_start_frequency,
&k0, &k2)) sbrHeaderData->sbr_stop_frequency,
&k0,
&k2
)
)
return(1); return(1);
if(FDKsbrEnc_UpdateFreqScale(sbrConfigData->v_k_master, &sbrConfigData->num_Master, if( FDKsbrEnc_UpdateFreqScale(
k0, k2, sbrHeaderData->freqScale, sbrConfigData->v_k_master,
sbrHeaderData->alterScale)) &sbrConfigData->num_Master,
k0,
k2,
sbrHeaderData->freqScale,
sbrHeaderData->alterScale
)
)
return(1); return(1);
sbrHeaderData->sbr_xover_band=0; sbrHeaderData->sbr_xover_band=0;
if(FDKsbrEnc_UpdateHiRes(sbrConfigData->freqBandTable[HI], if( FDKsbrEnc_UpdateHiRes(
&sbrConfigData->nSfb[HI], sbrConfigData->freqBandTable[HI],
sbrConfigData->v_k_master, &sbrConfigData->nSfb[HI],
sbrConfigData->num_Master , sbrConfigData->v_k_master,
&sbrHeaderData->sbr_xover_band, sbrConfigData->num_Master,
sbrHeaderData->sampleRateMode, &sbrHeaderData->sbr_xover_band
noQmfChannels)) )
)
return(1); return(1);
FDKsbrEnc_UpdateLoRes(sbrConfigData->freqBandTable[LO], FDKsbrEnc_UpdateLoRes(
&sbrConfigData->nSfb[LO], sbrConfigData->freqBandTable[LO],
sbrConfigData->freqBandTable[HI], &sbrConfigData->nSfb[LO],
sbrConfigData->nSfb[HI]); sbrConfigData->freqBandTable[HI],
sbrConfigData->nSfb[HI]
);
sbrConfigData->xOverFreq = (sbrConfigData->freqBandTable[LOW_RES][0] * sbrConfigData->sampleFreq / noQmfChannels+1)>>1; sbrConfigData->xOverFreq = (sbrConfigData->freqBandTable[LOW_RES][0] * sbrConfigData->sampleFreq / sbrConfigData->noQmfBands+1)>>1;
return (0); return (0);
} }
...@@ -866,7 +934,8 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, ...@@ -866,7 +934,8 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
*/ */
if(updateFreqBandTable(&hSbrElement->sbrConfigData, if(updateFreqBandTable(&hSbrElement->sbrConfigData,
&hSbrElement->sbrHeaderData, &hSbrElement->sbrHeaderData,
hSbrElement->sbrConfigData.noQmfBands)) hEnvEncoder->downSampleFactor
))
return(1); return(1);
...@@ -891,8 +960,6 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, ...@@ -891,8 +960,6 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
&crcInfo, &crcInfo,
hSbrElement->sbrConfigData.sbrSyntaxFlags); hSbrElement->sbrConfigData.sbrSyntaxFlags);
INT error = noError;
/* Temporal Envelope Data */ /* Temporal Envelope Data */
SBR_FRAME_TEMP_DATA _fData; SBR_FRAME_TEMP_DATA _fData;
SBR_FRAME_TEMP_DATA *fData = &_fData; SBR_FRAME_TEMP_DATA *fData = &_fData;
...@@ -923,9 +990,9 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, ...@@ -923,9 +990,9 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
if(hSbrElement->elInfo.fParametricStereo == 0) if(hSbrElement->elInfo.fParametricStereo == 0)
{ {
C_ALLOC_SCRATCH_START(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2);
QMF_SCALE_FACTOR tmpScale; QMF_SCALE_FACTOR tmpScale;
FIXP_DBL **pQmfReal, **pQmfImag; FIXP_DBL **pQmfReal, **pQmfImag;
C_AALLOC_SCRATCH_START(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2)
/* Obtain pointers to QMF buffers. */ /* Obtain pointers to QMF buffers. */
...@@ -940,10 +1007,11 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, ...@@ -940,10 +1007,11 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
timeInStride, timeInStride,
qmfWorkBuffer ); qmfWorkBuffer );
C_ALLOC_SCRATCH_END(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2);
h_envChan->qmfScale = tmpScale.lb_scale + 7; h_envChan->qmfScale = tmpScale.lb_scale + 7;
C_AALLOC_SCRATCH_END(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2)
} /* fParametricStereo == 0 */ } /* fParametricStereo == 0 */
...@@ -952,6 +1020,8 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, ...@@ -952,6 +1020,8 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
*/ */
if (hSbrElement->elInfo.fParametricStereo) if (hSbrElement->elInfo.fParametricStereo)
{ {
INT error = noError;
/* Limit Parametric Stereo to one instance */ /* Limit Parametric Stereo to one instance */
FDK_ASSERT(ch == 0); FDK_ASSERT(ch == 0);
...@@ -1177,10 +1247,12 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData, ...@@ -1177,10 +1247,12 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
break; break;
case 2048: case 2048:
case 1024: case 1024:
case 512:
timeSlots = 16; timeSlots = 16;
break; break;
case 1920: case 1920:
case 960: case 960:
case 480:
timeSlots = 15; timeSlots = 15;
break; break;
case 1152: case 1152:
...@@ -1221,9 +1293,9 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData, ...@@ -1221,9 +1293,9 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
tran_fc = params->tran_fc; tran_fc = params->tran_fc;
if (tran_fc == 0) if (tran_fc == 0) {
tran_fc = fixMin (5000, FDKsbrEnc_getSbrStartFreqRAW (sbrHeaderData->sbr_start_frequency,64,sbrConfigData->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;
...@@ -1233,11 +1305,11 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData, ...@@ -1233,11 +1305,11 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
} else } else
{ {
frameShift = 0; frameShift = 0;
switch (params->sbrFrameSize) { switch (timeSlots) {
/* The factor of 2 is by definition. */ /* The factor of 2 is by definition. */
case 2048: tran_off = 8 + FRAME_MIDDLE_SLOT_2048 * timeStep; break; case NUMBER_TIME_SLOTS_2048: tran_off = 8 + FRAME_MIDDLE_SLOT_2048 * timeStep; break;
case 1920: tran_off = 7 + FRAME_MIDDLE_SLOT_1920 * timeStep; break; case NUMBER_TIME_SLOTS_1920: tran_off = 7 + FRAME_MIDDLE_SLOT_1920 * timeStep; break;
default: return 1; break; default: return 1;
} }
} }
if ( FDKsbrEnc_InitExtractSbrEnvelope (&hEnv->sbrExtractEnvelope, if ( FDKsbrEnc_InitExtractSbrEnvelope (&hEnv->sbrExtractEnvelope,
...@@ -1330,7 +1402,6 @@ INT sbrEncoder_Open( ...@@ -1330,7 +1402,6 @@ INT sbrEncoder_Open(
hSbrEncoder->pSBRdynamic_RAM = (UCHAR*)GetRam_SbrDynamic_RAM(); hSbrEncoder->pSBRdynamic_RAM = (UCHAR*)GetRam_SbrDynamic_RAM();
hSbrEncoder->dynamicRam = hSbrEncoder->pSBRdynamic_RAM; hSbrEncoder->dynamicRam = hSbrEncoder->pSBRdynamic_RAM;
for (i=0; i<nElements; i++) { for (i=0; i<nElements; i++) {
hSbrEncoder->sbrElement[i] = GetRam_SbrElement(i); hSbrEncoder->sbrElement[i] = GetRam_SbrElement(i);
if (hSbrEncoder->sbrElement[i]==NULL) { if (hSbrEncoder->sbrElement[i]==NULL) {
...@@ -1463,7 +1534,8 @@ INT FDKsbrEnc_EnvInit ( ...@@ -1463,7 +1534,8 @@ INT FDKsbrEnc_EnvInit (
int nBitstrDelay, int nBitstrDelay,
int nElement, int nElement,
const int headerPeriod, const int headerPeriod,
ULONG statesInitFlag ULONG statesInitFlag,
int fTimeDomainDownsampling
,UCHAR *dynamic_RAM ,UCHAR *dynamic_RAM
) )
{ {
...@@ -1497,8 +1569,16 @@ INT FDKsbrEnc_EnvInit ( ...@@ -1497,8 +1569,16 @@ INT FDKsbrEnc_EnvInit (
hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC; hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC;
} }
hSbrElement->sbrConfigData.noQmfBands = QMF_CHANNELS; hSbrElement->sbrConfigData.noQmfBands = QMF_CHANNELS>>(2-params->downSampleFactor);
hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize/hSbrElement->sbrConfigData.noQmfBands; 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); FDKinitBitStream(&hSbrElement->CmonData.sbrBitbuf, bitstreamBuffer, MAX_PAYLOAD_SIZE*sizeof(UCHAR), 0, BS_WRITER);
...@@ -1514,10 +1594,7 @@ INT FDKsbrEnc_EnvInit ( ...@@ -1514,10 +1594,7 @@ INT FDKsbrEnc_EnvInit (
hSbrElement->sbrConfigData.frameSize = params->sbrFrameSize; hSbrElement->sbrConfigData.frameSize = params->sbrFrameSize;
/* implicit rule for sampleRateMode */ hSbrElement->sbrConfigData.sampleFreq = params->downSampleFactor * params->codecSettings.sampleFreq;
/* run in "multirate" mode where sbr fs is 2 * codec fs */
hSbrElement->sbrHeaderData.sampleRateMode = DUAL_RATE;
hSbrElement->sbrConfigData.sampleFreq = 2 * params->codecSettings.sampleFreq;
hSbrElement->sbrBitstreamData.CountSendHeaderData = 0; hSbrElement->sbrBitstreamData.CountSendHeaderData = 0;
if (params->SendHeaderDataTime > 0 ) { if (params->SendHeaderDataTime > 0 ) {
...@@ -1592,7 +1669,8 @@ INT FDKsbrEnc_EnvInit ( ...@@ -1592,7 +1669,8 @@ INT FDKsbrEnc_EnvInit (
/* init freq band table */ /* init freq band table */
if(updateFreqBandTable(&hSbrElement->sbrConfigData, if(updateFreqBandTable(&hSbrElement->sbrConfigData,
&hSbrElement->sbrHeaderData, &hSbrElement->sbrHeaderData,
hSbrElement->sbrConfigData.noQmfBands)) params->downSampleFactor
))
{ {
return(1); return(1);
} }
...@@ -1632,6 +1710,9 @@ INT FDKsbrEnc_EnvInit ( ...@@ -1632,6 +1710,9 @@ INT FDKsbrEnc_EnvInit (
hSbrElement->sbrConfigData.noQmfBands, hSbrElement->sbrConfigData.noQmfBands,
hSbrElement->sbrConfigData.noQmfBands, hSbrElement->sbrConfigData.noQmfBands,
qmfFlags ); qmfFlags );
if (0!=err) {
return err;
}
} }
/* */ /* */
...@@ -1653,7 +1734,7 @@ INT sbrEncoder_GetInBufferSize(int noChannels) ...@@ -1653,7 +1734,7 @@ INT sbrEncoder_GetInBufferSize(int noChannels)
{ {
INT temp; INT temp;
temp = (1024*DOWN_SMPL_FAC); temp = (2048);
temp += 1024 + MAX_SAMPLE_DELAY; temp += 1024 + MAX_SAMPLE_DELAY;
temp *= noChannels; temp *= noChannels;
temp *= sizeof(INT_PCM); temp *= sizeof(INT_PCM);
...@@ -1685,8 +1766,8 @@ INT FDKsbrEnc_DelayCompensation ( ...@@ -1685,8 +1766,8 @@ INT FDKsbrEnc_DelayCompensation (
1 1
)) ))
return -1; return -1;
sbrEncoder_UpdateBuffers(hEnvEnc, timeBuffer);
} }
sbrEncoder_UpdateBuffers(hEnvEnc, timeBuffer);
} }
return 0; return 0;
} }
...@@ -1717,30 +1798,36 @@ UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate ...@@ -1717,30 +1798,36 @@ UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate
return newBitRate; return newBitRate;
} }
UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot)
{
UINT isPossible=(AOT_PS==aot)?0:1;
return isPossible;
}
INT sbrEncoder_Init( INT sbrEncoder_Init(
HANDLE_SBR_ENCODER hSbrEncoder, HANDLE_SBR_ENCODER hSbrEncoder,
SBR_ELEMENT_INFO elInfo[(6)], SBR_ELEMENT_INFO elInfo[(6)],
int noElements, int noElements,
INT_PCM *inputBuffer, INT_PCM *inputBuffer,
INT *coreBandwidth, INT *coreBandwidth,
INT *inputBufferOffset, INT *inputBufferOffset,
INT *numChannels, INT *numChannels,
INT *sampleRate, INT *coreSampleRate,
INT *frameLength, UINT *downSampleFactor,
AUDIO_OBJECT_TYPE *aot, INT *frameLength,
int *delay, AUDIO_OBJECT_TYPE aot,
int transformFactor, int *delay,
const int headerPeriod, int transformFactor,
ULONG statesInitFlag const int headerPeriod,
) ULONG statesInitFlag
)
{ {
HANDLE_ERROR_INFO errorInfo = noError; HANDLE_ERROR_INFO errorInfo = noError;
sbrConfiguration sbrConfig[(6)]; sbrConfiguration sbrConfig[(6)];
INT error = 0; INT error = 0;
INT lowestBandwidth; INT lowestBandwidth;
/* Save input parameters */ /* Save input parameters */
INT inputSampleRate = *sampleRate; INT inputSampleRate = *coreSampleRate;
int coreFrameLength = *frameLength; int coreFrameLength = *frameLength;
int inputBandWidth = *coreBandwidth; int inputBandWidth = *coreBandwidth;
int inputChannels = *numChannels; int inputChannels = *numChannels;
...@@ -1748,20 +1835,26 @@ INT sbrEncoder_Init( ...@@ -1748,20 +1835,26 @@ INT sbrEncoder_Init(
int downsampledOffset = 0; int downsampledOffset = 0;
int sbrOffset = 0; int sbrOffset = 0;
int downsamplerDelay = 0; int downsamplerDelay = 0;
int downsample = 0; int timeDomainDownsample = 0;
int nBitstrDelay = 0; int nBitstrDelay = 0;
int lowestSbrStartFreq, lowestSbrStopFreq; int highestSbrStartFreq, highestSbrStopFreq;
int lowDelay = 0; int lowDelay = 0;
int usePs = 0; int usePs = 0;
/* check whether SBR setting is available for the current encoder configuration (bitrate, samplerate) */ /* check whether SBR setting is available for the current encoder configuration (bitrate, samplerate) */
if ( (*aot==AOT_PS) || (*aot==AOT_MP2_PS) || (*aot==AOT_DABPLUS_PS) || (*aot==AOT_DRM_MPEG_PS) ) { if (!sbrEncoder_IsSingleRatePossible(aot)) {
*downSampleFactor = 2;
}
if ( (aot==AOT_PS) || (aot==AOT_MP2_PS) || (aot==AOT_DABPLUS_PS) || (aot==AOT_DRM_MPEG_PS) ) {
usePs = 1; usePs = 1;
} }
if ( (*aot==AOT_ER_AAC_ELD) ) { if ( (aot==AOT_ER_AAC_ELD) ) {
lowDelay = 1; lowDelay = 1;
} }
else if ( (*aot==AOT_ER_AAC_LD) ) { else if ( (aot==AOT_ER_AAC_LD) ) {
error = 1; error = 1;
goto bail; goto bail;
} }
...@@ -1776,25 +1869,25 @@ INT sbrEncoder_Init( ...@@ -1776,25 +1869,25 @@ INT sbrEncoder_Init(
/* core encoder gets downmixed mono signal */ /* core encoder gets downmixed mono signal */
*numChannels = 1; *numChannels = 1;
} else { } else {
switch (*aot) { error = 1;
case AOT_MP2_PS: goto bail;
*aot = AOT_MP2_SBR;
break;
case AOT_DABPLUS_PS:
*aot = AOT_DABPLUS_SBR;
break;
case AOT_DRM_MPEG_PS:
*aot = AOT_DRM_SBR;
break;
case AOT_PS:
default:
*aot = AOT_SBR;
}
usePs = 0;
} }
} /* usePs */ } /* usePs */
/* check whether SBR setting is available for the current encoder configuration (bitrate, samplerate) */ /* set the core's sample rate */
switch (*downSampleFactor) {
case 1:
*coreSampleRate = inputSampleRate;
break;
case 2:
*coreSampleRate = inputSampleRate>>1;
break;
default:
*coreSampleRate = inputSampleRate>>1;
return 0; /* return error */
}
/* check whether SBR setting is available for the current encoder configuration (bitrate, coreSampleRate) */
{ {
int delayDiff = 0; int delayDiff = 0;
int el, coreEl; int el, coreEl;
...@@ -1807,54 +1900,37 @@ INT sbrEncoder_Init( ...@@ -1807,54 +1900,37 @@ INT sbrEncoder_Init(
continue; continue;
} }
/* check if desired configuration is available */ /* check if desired configuration is available */
if ( !FDKsbrEnc_IsSbrSettingAvail (elInfo[coreEl].bitRate, 0, elInfo[coreEl].nChannelsInEl, inputSampleRate, *aot) ) if ( !FDKsbrEnc_IsSbrSettingAvail (elInfo[coreEl].bitRate, 0, elInfo[coreEl].nChannelsInEl, inputSampleRate, *coreSampleRate, aot) )
{ {
/* otherwise - change to AAC-LC */
switch (*aot) {
case AOT_MP2_SBR:
case AOT_MP2_PS:
*aot = AOT_MP2_AAC_LC;
break;
case AOT_DABPLUS_SBR:
case AOT_DABPLUS_PS:
*aot = AOT_DABPLUS_AAC_LC;
break;
case AOT_DRM_SBR:
case AOT_DRM_MPEG_PS:
*aot = AOT_DRM_AAC;
break;
case AOT_ER_AAC_ELD:
break;
case AOT_SBR:
case AOT_PS:
default:
*aot = AOT_AAC_LC;
}
error = 1; error = 1;
goto bail; goto bail;
} }
} }
*sampleRate /= DOWN_SMPL_FAC;
/* Determine Delay balancing and new encoder delay */ /* Determine Delay balancing and new encoder delay */
if (lowDelay) { if (lowDelay) {
downsample = 1; /* activate downsampler */ {
delayDiff = (*delay*DOWN_SMPL_FAC) + DELAY_ELD2SBR(coreFrameLength); delayDiff = (*delay * *downSampleFactor) + DELAY_ELD2SBR(coreFrameLength,*downSampleFactor);
*delay = DELAY_ELDSBR(coreFrameLength); *delay = DELAY_ELDSBR(coreFrameLength,*downSampleFactor);
}
} }
else if (usePs) { else if (usePs) {
delayDiff = (*delay*DOWN_SMPL_FAC) + DELAY_AAC2PS(coreFrameLength); delayDiff = (*delay * *downSampleFactor) + DELAY_AAC2PS(coreFrameLength,*downSampleFactor);
*delay = DELAY_PS(coreFrameLength); *delay = DELAY_PS(coreFrameLength,*downSampleFactor);
} }
else { else {
downsample = 1; /* activate downsampler */ delayDiff = DELAY_AAC2SBR(coreFrameLength,*downSampleFactor);
delayDiff = (*delay*DOWN_SMPL_FAC) + DELAY_AAC2SBR(coreFrameLength); delayDiff += (*delay * *downSampleFactor);
*delay = DELAY_SBR(coreFrameLength); *delay = DELAY_SBR(coreFrameLength,*downSampleFactor);
}
if (!usePs) {
timeDomainDownsample = *downSampleFactor-1; /* activate time domain downsampler when downSampleFactor is != 1 */
} }
/* Take care about downsampled data bound to the SBR path */ /* Take care about downsampled data bound to the SBR path */
if (!downsample && delayDiff > 0) { if (!timeDomainDownsample && delayDiff > 0) {
/* /*
* We must tweak the balancing into a situation where the downsampled path * 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 * is the one to be delayed, because delaying the QMF domain input, also delays
...@@ -1863,12 +1939,15 @@ INT sbrEncoder_Init( ...@@ -1863,12 +1939,15 @@ INT sbrEncoder_Init(
while ( delayDiff > 0 ) while ( delayDiff > 0 )
{ {
/* Encoder delay increases */ /* Encoder delay increases */
*delay += coreFrameLength*DOWN_SMPL_FAC; {
/* Add one frame delay to SBR path */ *delay += coreFrameLength * *downSampleFactor;
delayDiff -= coreFrameLength*DOWN_SMPL_FAC; /* Add one frame delay to SBR path */
delayDiff -= coreFrameLength * *downSampleFactor;
}
nBitstrDelay += 1; nBitstrDelay += 1;
} }
} else { } else
{
*delay += fixp_abs(delayDiff); *delay += fixp_abs(delayDiff);
} }
...@@ -1876,32 +1955,33 @@ INT sbrEncoder_Init( ...@@ -1876,32 +1955,33 @@ INT sbrEncoder_Init(
/* Delay AAC data */ /* Delay AAC data */
delayDiff = -delayDiff; delayDiff = -delayDiff;
/* Multiply downsampled offset by AAC core channels. Divide by 2 because of half samplerate of downsampled data. */ /* Multiply downsampled offset by AAC core channels. Divide by 2 because of half samplerate of downsampled data. */
downsampledOffset = (delayDiff*(*numChannels))/DOWN_SMPL_FAC; FDK_ASSERT(*downSampleFactor>0 && *downSampleFactor<=2);
downsampledOffset = (delayDiff*(*numChannels))>>(*downSampleFactor-1);
sbrOffset = 0; sbrOffset = 0;
} else { } else {
/* Delay SBR input */ /* Delay SBR input */
if ( delayDiff > (int)coreFrameLength*DOWN_SMPL_FAC ) if ( delayDiff > (int)coreFrameLength * (int)*downSampleFactor )
{ {
/* Do bitstream frame-wise delay balancing if we have more than SBR framelength samples delay difference */ /* Do bitstream frame-wise delay balancing if we have more than SBR framelength samples delay difference */
delayDiff -= coreFrameLength*DOWN_SMPL_FAC; delayDiff -= coreFrameLength * *downSampleFactor;
nBitstrDelay = 1; nBitstrDelay = 1;
} }
/* Multiply input offset by input channels */ /* Multiply input offset by input channels */
sbrOffset = delayDiff*(*numChannels); sbrOffset = delayDiff*(*numChannels);
downsampledOffset = 0; downsampledOffset = 0;
} }
hSbrEncoder->nBitstrDelay = nBitstrDelay;
hSbrEncoder->nBitstrDelay = nBitstrDelay; hSbrEncoder->nChannels = *numChannels;
hSbrEncoder->nChannels = *numChannels; hSbrEncoder->frameSize = coreFrameLength * *downSampleFactor;
hSbrEncoder->frameSize = *frameLength*DOWN_SMPL_FAC; hSbrEncoder->fTimeDomainDownsampling = timeDomainDownsample;
hSbrEncoder->fTimeDomainDownsampling = downsample; hSbrEncoder->downSampleFactor = *downSampleFactor;
hSbrEncoder->estimateBitrate = 0; hSbrEncoder->estimateBitrate = 0;
hSbrEncoder->inputDataDelay = 0; hSbrEncoder->inputDataDelay = 0;
/* Open SBR elements */ /* Open SBR elements */
el = -1; el = -1;
lowestSbrStartFreq = lowestSbrStopFreq = 9999; highestSbrStartFreq = highestSbrStopFreq = 0;
lowestBandwidth = 99999; lowestBandwidth = 99999;
/* Loop through each core encoder element and get a matching SBR element config */ /* Loop through each core encoder element and get a matching SBR element config */
...@@ -1924,28 +2004,38 @@ INT sbrEncoder_Init( ...@@ -1924,28 +2004,38 @@ INT sbrEncoder_Init(
/* /*
* Init sbrConfig structure * Init sbrConfig structure
*/ */
FDKsbrEnc_InitializeSbrDefaults ( &sbrConfig[el], if ( ! FDKsbrEnc_InitializeSbrDefaults ( &sbrConfig[el],
DOWN_SMPL_FAC, *downSampleFactor,
coreFrameLength); coreFrameLength
) )
{
error = 1;
goto bail;
}
/* /*
* Modify sbrConfig structure according to Element parameters * Modify sbrConfig structure according to Element parameters
*/ */
FDKsbrEnc_AdjustSbrSettings ( &sbrConfig[el], if ( ! FDKsbrEnc_AdjustSbrSettings (&sbrConfig[el],
elInfo[coreEl].bitRate, elInfo[coreEl].bitRate,
elInfo[coreEl].nChannelsInEl, elInfo[coreEl].nChannelsInEl,
*sampleRate, *coreSampleRate,
transformFactor, inputSampleRate,
24000, transformFactor,
0, 24000,
0, /* useSpeechConfig */ 0,
0, /* lcsMode */ 0, /* useSpeechConfig */
usePs, /* bParametricStereo */ 0, /* lcsMode */
*aot); usePs, /* bParametricStereo */
aot) )
{
error = 1;
goto bail;
}
/* Find common frequency border for all SBR elements */ /* Find common frequency border for all SBR elements */
lowestSbrStartFreq = fixMin(lowestSbrStartFreq, sbrConfig[el].startFreq); highestSbrStartFreq = fixMax(highestSbrStartFreq, sbrConfig[el].startFreq);
lowestSbrStopFreq = fixMin(lowestSbrStopFreq, sbrConfig[el].stopFreq); highestSbrStopFreq = fixMax(highestSbrStopFreq, sbrConfig[el].stopFreq);
} /* first element loop */ } /* first element loop */
...@@ -1961,22 +2051,24 @@ INT sbrEncoder_Init( ...@@ -1961,22 +2051,24 @@ INT sbrEncoder_Init(
int bandwidth = *coreBandwidth; int bandwidth = *coreBandwidth;
/* Use lowest common bandwidth */ /* Use lowest common bandwidth */
sbrConfig[el].startFreq = lowestSbrStartFreq; sbrConfig[el].startFreq = highestSbrStartFreq;
sbrConfig[el].stopFreq = lowestSbrStopFreq; sbrConfig[el].stopFreq = highestSbrStopFreq;
/* initialize SBR element, and get core bandwidth */ /* initialize SBR element, and get core bandwidth */
error = FDKsbrEnc_EnvInit(hSbrEncoder->sbrElement[el], error = FDKsbrEnc_EnvInit(hSbrEncoder->sbrElement[el],
&sbrConfig[el], &sbrConfig[el],
&bandwidth, &bandwidth,
*aot, aot,
nBitstrDelay, nBitstrDelay,
el, el,
headerPeriod, headerPeriod,
statesInitFlag statesInitFlag,
hSbrEncoder->fTimeDomainDownsampling
,hSbrEncoder->dynamicRam ,hSbrEncoder->dynamicRam
); );
if (error != 0) { if (error != 0) {
error = 2;
goto bail; goto bail;
} }
...@@ -1998,30 +2090,29 @@ INT sbrEncoder_Init( ...@@ -1998,30 +2090,29 @@ INT sbrEncoder_Init(
for (ch=0; ch<hSbrEl->elInfo.nChannelsInEl; ch++) for (ch=0; ch<hSbrEl->elInfo.nChannelsInEl; ch++)
{ {
FDKaacEnc_InitDownsampler (&hSbrEl->sbrChannel[ch]->downSampler, Wc, DOWN_SMPL_FAC); FDKaacEnc_InitDownsampler (&hSbrEl->sbrChannel[ch]->downSampler, Wc, *downSampleFactor);
FDK_ASSERT (hSbrEl->sbrChannel[ch]->downSampler.delay <=MAX_DS_FILTER_DELAY);
} }
FDK_ASSERT (hSbrEl->sbrChannel[0]->downSampler.delay <=MAX_DS_FILTER_DELAY && hSbrEl->sbrChannel[0]->downSampler.delay <=MAX_DS_FILTER_DELAY);
downsamplerDelay = hSbrEl->sbrChannel[0]->downSampler.delay; downsamplerDelay = hSbrEl->sbrChannel[0]->downSampler.delay;
} /* third element loop */ } /* third element loop */
/* lfe */ /* lfe */
FDKaacEnc_InitDownsampler (&hSbrEncoder->lfeDownSampler, 0, DOWN_SMPL_FAC); FDKaacEnc_InitDownsampler (&hSbrEncoder->lfeDownSampler, 0, *downSampleFactor);
/* Add the resampler additional delay to get the final delay and buffer offset values. */ /* Add the resampler additional delay to get the final delay and buffer offset values. */
if (sbrOffset > 0 || downsampledOffset <= ((downsamplerDelay * (*numChannels))/DOWN_SMPL_FAC)) { if (sbrOffset > 0 || downsampledOffset <= ((downsamplerDelay * (*numChannels))>>(*downSampleFactor-1))) {
sbrOffset += (downsamplerDelay - downsampledOffset) * (*numChannels) ; sbrOffset += (downsamplerDelay - downsampledOffset) * (*numChannels) ;
*delay += downsamplerDelay - downsampledOffset; *delay += downsamplerDelay - downsampledOffset;
downsampledOffset = 0; downsampledOffset = 0;
} else { } else {
downsampledOffset -= (downsamplerDelay * (*numChannels))/DOWN_SMPL_FAC; downsampledOffset -= (downsamplerDelay * (*numChannels))>>(*downSampleFactor-1);
sbrOffset = 0; sbrOffset = 0;
} }
hSbrEncoder->inputDataDelay = downsamplerDelay; hSbrEncoder->inputDataDelay = downsamplerDelay;
} }
/* Assign core encoder Bandwidth */ /* Assign core encoder Bandwidth */
*coreBandwidth = lowestBandwidth; *coreBandwidth = lowestBandwidth;
...@@ -2035,7 +2126,7 @@ INT sbrEncoder_Init( ...@@ -2035,7 +2126,7 @@ INT sbrEncoder_Init(
FDK_ASSERT(hSbrEncoder->noElements == 1); FDK_ASSERT(hSbrEncoder->noElements == 1);
INT psTuningTableIdx = getPsTuningTableIndex(elInfo[0].bitRate, NULL); INT psTuningTableIdx = getPsTuningTableIndex(elInfo[0].bitRate, NULL);
psEncConfig.frameSize = *frameLength; //sbrConfig.sbrFrameSize; psEncConfig.frameSize = coreFrameLength; //sbrConfig.sbrFrameSize;
psEncConfig.qmfFilterMode = 0; psEncConfig.qmfFilterMode = 0;
psEncConfig.sbrPsDelay = 0; psEncConfig.sbrPsDelay = 0;
...@@ -2047,7 +2138,7 @@ INT sbrEncoder_Init( ...@@ -2047,7 +2138,7 @@ INT sbrEncoder_Init(
/* calculation is not quite linear, increased number of envelopes causes more bits */ /* 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 */ /* assume avg. 50 bits per frame for 10 stereo bands / 1 envelope configuration */
hSbrEncoder->estimateBitrate += ( (((*sampleRate) * 5 * psEncConfig.nStereoBands * psEncConfig.maxEnvelopes) / hSbrEncoder->frameSize)); hSbrEncoder->estimateBitrate += ( (((*coreSampleRate) * 5 * psEncConfig.nStereoBands * psEncConfig.maxEnvelopes) / hSbrEncoder->frameSize));
} else { } else {
error = ERROR(CDI, "Invalid ps tuning table index."); error = ERROR(CDI, "Invalid ps tuning table index.");
...@@ -2076,10 +2167,16 @@ INT sbrEncoder_Init( ...@@ -2076,10 +2167,16 @@ INT sbrEncoder_Init(
errorInfo = handBack(errorInfo); errorInfo = handBack(errorInfo);
} }
} }
/* 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);
} }
hSbrEncoder->downsampledOffset = downsampledOffset; hSbrEncoder->downsampledOffset = downsampledOffset;
hSbrEncoder->downmixSize = coreFrameLength*(*numChannels); {
hSbrEncoder->downmixSize = coreFrameLength*(*numChannels);
}
hSbrEncoder->bufferOffset = sbrOffset; hSbrEncoder->bufferOffset = sbrOffset;
/* Delay Compensation: fill bitstream delay buffer with zero input signal */ /* Delay Compensation: fill bitstream delay buffer with zero input signal */
if ( hSbrEncoder->nBitstrDelay > 0 ) if ( hSbrEncoder->nBitstrDelay > 0 )
...@@ -2090,7 +2187,7 @@ INT sbrEncoder_Init( ...@@ -2090,7 +2187,7 @@ INT sbrEncoder_Init(
} }
/* Set Output frame length */ /* Set Output frame length */
*frameLength = coreFrameLength*DOWN_SMPL_FAC; *frameLength = coreFrameLength * *downSampleFactor;
/* Input buffer offset */ /* Input buffer offset */
*inputBufferOffset = fixMax(sbrOffset, downsampledOffset); *inputBufferOffset = fixMax(sbrOffset, downsampledOffset);
...@@ -2101,7 +2198,7 @@ INT sbrEncoder_Init( ...@@ -2101,7 +2198,7 @@ INT sbrEncoder_Init(
bail: bail:
/* Restore input settings */ /* Restore input settings */
*sampleRate = inputSampleRate; *coreSampleRate = inputSampleRate;
*frameLength = coreFrameLength; *frameLength = coreFrameLength;
*numChannels = inputChannels; *numChannels = inputChannels;
*coreBandwidth = inputBandWidth; *coreBandwidth = inputBandWidth;
...@@ -2139,8 +2236,8 @@ sbrEncoder_EncodeFrame( HANDLE_SBR_ENCODER hSbrEncoder, ...@@ -2139,8 +2236,8 @@ sbrEncoder_EncodeFrame( HANDLE_SBR_ENCODER hSbrEncoder,
} }
} }
if ( (hSbrEncoder->lfeChIdx!=-1) && (hSbrEncoder->fTimeDomainDownsampling) ) if ( ( hSbrEncoder->lfeChIdx!=-1) && (hSbrEncoder->downSampleFactor > 1) )
{ { /* lfe downsampler */
INT nOutSamples; INT nOutSamples;
FDKaacEnc_Downsample(&hSbrEncoder->lfeDownSampler, FDKaacEnc_Downsample(&hSbrEncoder->lfeDownSampler,
...@@ -2150,7 +2247,9 @@ sbrEncoder_EncodeFrame( HANDLE_SBR_ENCODER hSbrEncoder, ...@@ -2150,7 +2247,9 @@ sbrEncoder_EncodeFrame( HANDLE_SBR_ENCODER hSbrEncoder,
samples + hSbrEncoder->downsampledOffset + hSbrEncoder->lfeChIdx, samples + hSbrEncoder->downsampledOffset + hSbrEncoder->lfeChIdx,
&nOutSamples, &nOutSamples,
hSbrEncoder->nChannels); hSbrEncoder->nChannels);
} /* lfe downsampler */
}
return 0; return 0;
} }
......
...@@ -506,216 +506,277 @@ const UCHAR bookSbrNoiseBalanceL11T[25] = ...@@ -506,216 +506,277 @@ const UCHAR bookSbrNoiseBalanceL11T[25] =
/* /*
tuningTable tuningTable
*/ */
const sbrTuningTable_t sbrTuningTable[SBRENC_TUNING_SIZE] = const sbrTuningTable_t sbrTuningTable[] =
{ {
/* Some of the low bitrates are commented out here, this is because the
encoder could lose frames at those bitrates and throw an error because
it has insufficient bits to encode for some test items.
*/
/*** AAC ***/ /*** HE-AAC section ***/
/* sf,sfsp,sf,sfsp,nnb,nfo,saml,SM,FS*/ /* sf,sfsp,sf,sfsp,nnb,nfo,saml,SM,FS*/
/*** mono ***/ /*** mono ***/
/* 8/16 kHz dual rate */ /* 8/16 kHz dual rate */
{ 8000, 10000, 8000, 1, 7, 6, 11,10, 1, 0, 6, SBR_MONO, 3 }, { CODEC_AAC, 8000, 10000, 8000, 1, 7, 6, 11,10, 1, 0, 6, SBR_MONO, 3 },
{ 10000, 12000, 8000, 1, 11, 7, 13,12, 1, 0, 6, SBR_MONO, 3 }, { CODEC_AAC, 10000, 12000, 8000, 1, 11, 7, 13,12, 1, 0, 6, SBR_MONO, 3 },
{ 12000, 16001, 8000, 1, 14,10, 13,13, 1, 0, 6, SBR_MONO, 3 }, { CODEC_AAC, 12000, 16001, 8000, 1, 14,10, 13,13, 1, 0, 6, SBR_MONO, 3 },
{ 16000, 24000, 8000, 1, 14,10, 14,14, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ { CODEC_AAC, 16000, 24000, 8000, 1, 14,10, 14,14, 2, 0, 3, SBR_MONO, 2 }, /* placebo */
{ 24000, 32000, 8000, 1, 14,10, 14,14, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ { CODEC_AAC, 24000, 32000, 8000, 1, 14,10, 14,14, 2, 0, 3, SBR_MONO, 2 }, /* placebo */
{ 32000, 48001, 8000, 1, 14,11, 15,15, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ /* bitrates higher than 48000 not supported by AAC core */ { CODEC_AAC, 32000, 48001, 8000, 1, 14,11, 15,15, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ /* bitrates higher than 48000 not supported by AAC core */
/* 11/22 kHz dual rate */ /* 11/22 kHz dual rate */
{ 8000, 10000, 11025, 1, 5, 4, 6, 6, 1, 0, 6, SBR_MONO, 3 }, { CODEC_AAC, 8000, 10000, 11025, 1, 5, 4, 6, 6, 1, 0, 6, SBR_MONO, 3 },
{ 10000, 12000, 11025, 1, 8, 5, 12, 9, 1, 0, 6, SBR_MONO, 3 }, { CODEC_AAC, 10000, 12000, 11025, 1, 8, 5, 12, 9, 1, 0, 6, SBR_MONO, 3 },
{ 12000, 16000, 11025, 1, 12, 8, 13, 8, 1, 0, 6, SBR_MONO, 3 }, { CODEC_AAC, 12000, 16000, 11025, 1, 12, 8, 13, 8, 1, 0, 6, SBR_MONO, 3 },
{ 16000, 20000, 11025, 1, 12, 8, 13, 8, 1, 0, 6, SBR_MONO, 3 }, /* at such "high" bitrates it's better to upsample the input */ { CODEC_AAC, 16000, 20000, 11025, 1, 12, 8, 13, 8, 1, 0, 6, SBR_MONO, 3 }, /* at such "high" bitrates it's better to upsample the input */
{ 20000, 24001, 11025, 1, 13, 9, 13, 8, 1, 0, 6, SBR_MONO, 3 }, /* signal by a factor of 2 before sending it into the encoder */ { CODEC_AAC, 20000, 24001, 11025, 1, 13, 9, 13, 8, 1, 0, 6, SBR_MONO, 3 }, /* signal by a factor of 2 before sending it into the encoder */
{ 24000, 32000, 11025, 1, 14,10, 14, 9, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ { CODEC_AAC, 24000, 32000, 11025, 1, 14,10, 14, 9, 2, 0, 3, SBR_MONO, 2 }, /* placebo */
{ 32000, 48000, 11025, 1, 15,11, 15,10, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ { CODEC_AAC, 32000, 48000, 11025, 1, 15,11, 15,10, 2, 0, 3, SBR_MONO, 2 }, /* placebo */
{ 48000, 64001, 11025, 1, 15,11, 15,10, 2, 0, 3, SBR_MONO, 1 }, /* placebo */ { CODEC_AAC, 48000, 64001, 11025, 1, 15,11, 15,10, 2, 0, 3, SBR_MONO, 1 }, /* placebo */
/* 12/24 kHz dual rate */ /* 12/24 kHz dual rate */
{ 8000, 10000, 12000, 1, 4, 3, 6, 6, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 8 kbit/s */ { CODEC_AAC, 8000, 10000, 12000, 1, 4, 3, 6, 6, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 8 kbit/s */
{ 10000, 12000, 12000, 1, 7, 4, 11, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 10 kbit/s */ { CODEC_AAC, 10000, 12000, 12000, 1, 7, 4, 11, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 10 kbit/s */
{ 12000, 16000, 12000, 1, 11, 7, 12, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */ { CODEC_AAC, 12000, 16000, 12000, 1, 11, 7, 12, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */
{ 16000, 20000, 12000, 1, 11, 7, 12, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */ /* at such "high" bitrates it's better to upsample the input */ { CODEC_AAC, 16000, 20000, 12000, 1, 11, 7, 12, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */ /* at such "high" bitrates it's better to upsample the input */
{ 20000, 24001, 12000, 1, 12, 8, 12, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 20 kbit/s */ /* signal by a factor of 2 before sending it into the encoder */ { CODEC_AAC, 20000, 24001, 12000, 1, 12, 8, 12, 8, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 20 kbit/s */ /* signal by a factor of 2 before sending it into the encoder */
{ 24000, 32000, 12000, 1, 13, 9, 13, 9, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ { CODEC_AAC, 24000, 32000, 12000, 1, 13, 9, 13, 9, 2, 0, 3, SBR_MONO, 2 }, /* placebo */
{ 32000, 48000, 12000, 1, 14,10, 14,10, 2, 0, 3, SBR_MONO, 2 }, /* placebo */ { CODEC_AAC, 32000, 48000, 12000, 1, 14,10, 14,10, 2, 0, 3, SBR_MONO, 2 }, /* placebo */
{ 48000, 64001, 12000, 1, 15,11, 15,11, 2, 0, 3, SBR_MONO, 1 }, /* placebo */ { CODEC_AAC, 48000, 64001, 12000, 1, 14,11, 15,11, 2, 0, 3, SBR_MONO, 1 }, /* placebo */
/* 16/32 kHz dual rate */ /* 16/32 kHz dual rate */
{ 8000, 10000, 16000, 1, 1, 1, 0, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 8 kbit/s */ { CODEC_AAC, 8000, 10000, 16000, 1, 1, 1, 0, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 8 kbit/s */
{ 10000, 12000, 16000, 1, 2, 1, 6, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 10 kbit/s */ { CODEC_AAC, 10000, 12000, 16000, 1, 2, 1, 6, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 10 kbit/s */
{ 12000, 16000, 16000, 1, 4, 2, 6, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */ { CODEC_AAC, 12000, 16000, 16000, 1, 4, 2, 6, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */
{ 16000, 18000, 16000, 1, 4, 2, 8, 3, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */ { CODEC_AAC, 16000, 18000, 16000, 1, 4, 2, 8, 3, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */
{ 18000, 22000, 16000, 1, 6, 5,11, 7, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ { CODEC_AAC, 18000, 22000, 16000, 1, 6, 5,11, 7, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */
{ 22000, 28000, 16000, 1, 10, 9,12, 8, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ { CODEC_AAC, 22000, 28000, 16000, 1, 10, 9,12, 8, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */
{ 28000, 36000, 16000, 1, 12,12,13,13, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ { CODEC_AAC, 28000, 36000, 16000, 1, 12,12,13,13, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */
{ 36000, 44000, 16000, 1, 14,14,13,13, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ { CODEC_AAC, 36000, 44000, 16000, 1, 14,14,13,13, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */
{ 44000, 64001, 16000, 1, 15,15,13,13, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ { CODEC_AAC, 44000, 64001, 16000, 1, 14,14,13,13, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */
/* 22.05/44.1 kHz dual rate */ /* 22.05/44.1 kHz dual rate */
/* { 8000, 11369, 22050, 1, 1, 1, 1, 1, 1, 0, 6, SBR_MONO, 3 }, */ /* nominal: 8 kbit/s */ /* encoder can not work stable at this extremely low bitrate */ /* { CODEC_AAC, 8000, 11369, 22050, 1, 1, 1, 1, 1, 1, 0, 6, SBR_MONO, 3 }, */ /* nominal: 8 kbit/s */ /* encoder can not work stable at this extremely low bitrate */
{ 11369, 16000, 22050, 1, 3, 1, 4, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */ { CODEC_AAC, 11369, 16000, 22050, 1, 3, 1, 4, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */
{ 16000, 18000, 22050, 1, 3, 1, 5, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */ { CODEC_AAC, 16000, 18000, 22050, 1, 3, 1, 5, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */
{ 18000, 22000, 22050, 1, 4, 4, 8, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ { CODEC_AAC, 18000, 22000, 22050, 1, 4, 4, 8, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */
{ 22000, 28000, 22050, 1, 7, 6, 8, 6, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ { CODEC_AAC, 22000, 28000, 22050, 1, 7, 6, 8, 6, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */
{ 28000, 36000, 22050, 1, 10,10, 9, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ { CODEC_AAC, 28000, 36000, 22050, 1, 10,10, 9, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */
{ 36000, 44000, 22050, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ { CODEC_AAC, 36000, 44000, 22050, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */
{ 44000, 64001, 22050, 1, 13,13,12,12, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ { CODEC_AAC, 44000, 64001, 22050, 1, 13,13,12,12, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */
/* 24/48 kHz dual rate */ /* 24/48 kHz dual rate */
/* { 8000, 12000, 24000, 1, 1, 1, 1, 1, 1, 0, 6, SBR_MONO, 3 }, */ /* nominal: 8 kbit/s */ /* encoder can not work stable at this extremely low bitrate */ /* { CODEC_AAC, 8000, 12000, 24000, 1, 1, 1, 1, 1, 1, 0, 6, SBR_MONO, 3 }, */ /* nominal: 8 kbit/s */ /* encoder can not work stable at this extremely low bitrate */
{ 12000, 16000, 24000, 1, 3, 1, 4, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */ { CODEC_AAC, 12000, 16000, 24000, 1, 3, 1, 4, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 12 kbit/s */
{ 16000, 18000, 24000, 1, 3, 1, 5, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */ { CODEC_AAC, 16000, 18000, 24000, 1, 3, 1, 5, 4, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s */
{ 18000, 22000, 24000, 1, 4, 3, 8, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ { CODEC_AAC, 18000, 22000, 24000, 1, 4, 3, 8, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */
{ 22000, 28000, 24000, 1, 7, 6, 8, 6, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ { CODEC_AAC, 22000, 28000, 24000, 1, 7, 6, 8, 6, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */
{ 28000, 36000, 24000, 1, 10,10, 9, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ { CODEC_AAC, 28000, 36000, 24000, 1, 10,10, 9, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */
{ 36000, 44000, 24000, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ { CODEC_AAC, 36000, 44000, 24000, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */
{ 44000, 64001, 24000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ { CODEC_AAC, 44000, 64001, 24000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */
/* 32/64 kHz dual rate */ /* placebo settings */ /* 32/64 kHz dual rate */ /* placebo settings */
{ 24000, 36000, 32000, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3 }, /* lowest range */ { CODEC_AAC, 24000, 36000, 32000, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3 }, /* lowest range */
{ 36000, 60000, 32000, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2 }, /* lowest range */ { CODEC_AAC, 36000, 60000, 32000, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2 }, /* lowest range */
{ 60000, 72000, 32000, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1 }, /* low range */ { CODEC_AAC, 60000, 72000, 32000, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1 }, /* low range */
{ 72000,100000, 32000, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* SBR sweet spot */ { CODEC_AAC, 72000,100000, 32000, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* SBR sweet spot */
{ 100000,160001, 32000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* backwards compatible */ { CODEC_AAC, 100000,160001, 32000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* backwards compatible */
/* 44.1/88.2 kHz dual rate */ /* placebo settings */ /* 44.1/88.2 kHz dual rate */ /* placebo settings */
{ 24000, 36000, 44100, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3 }, /* lowest range (multichannel rear) */ { CODEC_AAC, 24000, 36000, 44100, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3 }, /* lowest range (multichannel rear) */
{ 36000, 60000, 44100, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2 }, /* lowest range (multichannel rear) */ { CODEC_AAC, 36000, 60000, 44100, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2 }, /* lowest range (multichannel rear) */
{ 60000, 72000, 44100, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1 }, /* low range */ { CODEC_AAC, 60000, 72000, 44100, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1 }, /* low range */
{ 72000,100000, 44100, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* SBR sweet spot */ { CODEC_AAC, 72000,100000, 44100, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* SBR sweet spot */
{ 100000,160001, 44100, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* backwards compatible */ { CODEC_AAC, 100000,160001, 44100, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* backwards compatible */
/* 48/96 kHz dual rate */ /* not yet finally tuned */ /* 48/96 kHz dual rate */ /* not yet finally tuned */
{ 32000, 36000, 48000, 1, 4, 4, 9, 9, 2, 0, 3, SBR_MONO, 3 }, /* lowest range (multichannel rear) */ { CODEC_AAC, 32000, 36000, 48000, 1, 4, 4, 9, 9, 2, 0, 3, SBR_MONO, 3 }, /* lowest range (multichannel rear) */
{ 36000, 60000, 48000, 1, 7, 7,10,10, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 40 */ { CODEC_AAC, 36000, 60000, 48000, 1, 7, 7,10,10, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 40 */
{ 60000, 72000, 48000, 1, 9, 9,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 */ { CODEC_AAC, 60000, 72000, 48000, 1, 9, 9,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 */
{ 72000,100000, 48000, 1, 11,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 80 */ { CODEC_AAC, 72000,100000, 48000, 1, 11,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 80 */
{ 100000,160001, 48000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */ { CODEC_AAC, 100000,160001, 48000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */
/*** stereo ***/ /*** stereo ***/
/* 08/16 kHz dual rate */ /* 08/16 kHz dual rate */
{ 16000, 24000, 8000, 2, 6, 6, 9, 7, 1, 0,-3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ /* placebo */ { CODEC_AAC, 16000, 24000, 8000, 2, 6, 6, 9, 7, 1, 0,-3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ /* placebo */
{ 24000, 28000, 8000, 2, 9, 9, 11, 9, 1, 0,-3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ { CODEC_AAC, 24000, 28000, 8000, 2, 9, 9, 11, 9, 1, 0,-3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */
{ 28000, 36000, 8000, 2, 11, 9, 11, 9, 2, 0,-3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ { CODEC_AAC, 28000, 36000, 8000, 2, 11, 9, 11, 9, 2, 0,-3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */
{ 36000, 44000, 8000, 2, 13,11, 13,11, 2, 0,-3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ { CODEC_AAC, 36000, 44000, 8000, 2, 13,11, 13,11, 2, 0,-3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */
{ 44000, 52000, 8000, 2, 14,12, 13,12, 2, 0,-3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ { CODEC_AAC, 44000, 52000, 8000, 2, 14,12, 13,12, 2, 0,-3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */
{ 52000, 60000, 8000, 2, 15,15, 13,13, 3, 0,-3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ { CODEC_AAC, 52000, 60000, 8000, 2, 14,14, 13,13, 3, 0,-3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */
{ 60000, 76000, 8000, 2, 15,15, 13,13, 3, 0,-3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ { CODEC_AAC, 60000, 76000, 8000, 2, 14,14, 13,13, 3, 0,-3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */
{ 76000,128001, 8000, 2, 15,15, 13,13, 3, 0,-3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ { CODEC_AAC, 76000,128001, 8000, 2, 14,14, 13,13, 3, 0,-3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */
/* 11/22 kHz dual rate */ /* 11/22 kHz dual rate */
{ 16000, 24000, 11025, 2, 7, 5, 9, 7, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ /* placebo */ { CODEC_AAC, 16000, 24000, 11025, 2, 7, 5, 9, 7, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ /* placebo */
{ 24000, 28000, 11025, 2, 10, 8,10, 8, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ { CODEC_AAC, 24000, 28000, 11025, 2, 10, 8,10, 8, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */
{ 28000, 36000, 11025, 2, 12, 8,12, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ { CODEC_AAC, 28000, 36000, 11025, 2, 12, 8,12, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */
{ 36000, 44000, 11025, 2, 13, 9,13, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ { CODEC_AAC, 36000, 44000, 11025, 2, 13, 9,13, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */
{ 44000, 52000, 11025, 2, 14,11,13,11, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ { CODEC_AAC, 44000, 52000, 11025, 2, 14,11,13,11, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */
{ 52000, 60000, 11025, 2, 15,15,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ { CODEC_AAC, 52000, 60000, 11025, 2, 15,15,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */
{ 60000, 76000, 11025, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ { CODEC_AAC, 60000, 76000, 11025, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */
{ 76000,128001, 11025, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ { CODEC_AAC, 76000,128001, 11025, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */
/* 12/24 kHz dual rate */ /* 12/24 kHz dual rate */
{ 16000, 24000, 12000, 2, 6, 4, 9, 7, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ /* placebo */ { CODEC_AAC, 16000, 24000, 12000, 2, 6, 4, 9, 7, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ /* placebo */
{ 24000, 28000, 12000, 2, 9, 7,10, 8, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ { CODEC_AAC, 24000, 28000, 12000, 2, 9, 7,10, 8, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */
{ 28000, 36000, 12000, 2, 11, 7,12, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ { CODEC_AAC, 28000, 36000, 12000, 2, 11, 7,12, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */
{ 36000, 44000, 12000, 2, 12, 9,12, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ { CODEC_AAC, 36000, 44000, 12000, 2, 12, 9,12, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */
{ 44000, 52000, 12000, 2, 13,12,13,12, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ { CODEC_AAC, 44000, 52000, 12000, 2, 13,12,13,12, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */
{ 52000, 60000, 12000, 2, 14,14,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ { CODEC_AAC, 52000, 60000, 12000, 2, 14,14,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */
{ 60000, 76000, 12000, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ { CODEC_AAC, 60000, 76000, 12000, 2, 14,14,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */
{ 76000,128001, 12000, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ { CODEC_AAC, 76000,128001, 12000, 2, 14,14,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */
/* 16/32 kHz dual rate */ /* 16/32 kHz dual rate */
{ 16000, 24000, 16000, 2, 4, 2, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ { CODEC_AAC, 16000, 24000, 16000, 2, 4, 2, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */
{ 24000, 28000, 16000, 2, 8, 7,10, 8, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ { CODEC_AAC, 24000, 28000, 16000, 2, 8, 7,10, 8, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */
{ 28000, 36000, 16000, 2, 10, 9,12,11, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ { CODEC_AAC, 28000, 36000, 16000, 2, 10, 9,12,11, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */
{ 36000, 44000, 16000, 2, 13,13,13,13, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ { CODEC_AAC, 36000, 44000, 16000, 2, 13,13,13,13, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */
{ 44000, 52000, 16000, 2, 15,15,13,13, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ { CODEC_AAC, 44000, 52000, 16000, 2, 14,14,13,13, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */
{ 52000, 60000, 16000, 2, 15,15,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ { CODEC_AAC, 52000, 60000, 16000, 2, 14,14,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */
{ 60000, 76000, 16000, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ { CODEC_AAC, 60000, 76000, 16000, 2, 14,14,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */
{ 76000,128001, 16000, 2, 15,15,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ { CODEC_AAC, 76000,128001, 16000, 2, 14,14,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */
/* 22.05/44.1 kHz dual rate */ /* 22.05/44.1 kHz dual rate */
{ 16000, 24000, 22050, 2, 2, 1, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ { CODEC_AAC, 16000, 24000, 22050, 2, 2, 1, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */
{ 24000, 28000, 22050, 2, 5, 4, 6, 5, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ { CODEC_AAC, 24000, 28000, 22050, 2, 5, 4, 6, 5, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */
{ 28000, 32000, 22050, 2, 5, 4, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 28 kbit/s */ { CODEC_AAC, 28000, 32000, 22050, 2, 5, 4, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 28 kbit/s */
{ 32000, 36000, 22050, 2, 7, 6, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ { CODEC_AAC, 32000, 36000, 22050, 2, 7, 6, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */
{ 36000, 44000, 22050, 2, 10,10, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ { CODEC_AAC, 36000, 44000, 22050, 2, 10,10, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */
{ 44000, 52000, 22050, 2, 12,12, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ { CODEC_AAC, 44000, 52000, 22050, 2, 12,12, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */
{ 52000, 60000, 22050, 2, 13,13,10,10, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ { CODEC_AAC, 52000, 60000, 22050, 2, 13,13,10,10, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */
{ 60000, 76000, 22050, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ { CODEC_AAC, 60000, 76000, 22050, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */
{ 76000,128001, 22050, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ { CODEC_AAC, 76000,128001, 22050, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */
/* 24/48 kHz dual rate */ /* 24/48 kHz dual rate */
{ 16000, 24000, 24000, 2, 2, 1, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */ { CODEC_AAC, 16000, 24000, 24000, 2, 2, 1, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 20 kbit/s */
{ 24000, 28000, 24000, 2, 5, 5, 6, 6, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */ { CODEC_AAC, 24000, 28000, 24000, 2, 5, 5, 6, 6, 1, 0, -3, SBR_SWITCH_LRC, 3 }, /* nominal: 24 kbit/s */
{ 28000, 36000, 24000, 2, 7, 6, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ { CODEC_AAC, 28000, 36000, 24000, 2, 7, 6, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */
{ 36000, 44000, 24000, 2, 10,10, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ { CODEC_AAC, 36000, 44000, 24000, 2, 10,10, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */
{ 44000, 52000, 24000, 2, 12,12, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ { CODEC_AAC, 44000, 52000, 24000, 2, 12,12, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */
{ 52000, 60000, 24000, 2, 13,13,10,10, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ { CODEC_AAC, 52000, 60000, 24000, 2, 13,13,10,10, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */
{ 60000, 76000, 24000, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ { CODEC_AAC, 60000, 76000, 24000, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */
{ 76000,128001, 24000, 2, 15,15,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ { CODEC_AAC, 76000,128001, 24000, 2, 14,14,12,12, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */
/* 32/64 kHz dual rate */ /* placebo settings */ /* 32/64 kHz dual rate */ /* placebo settings */
{ 32000, 60000, 32000, 2, 4, 4, 4, 4, 2, 0, -3, SBR_SWITCH_LRC, 3 }, /* lowest range (multichannel rear) */ { CODEC_AAC, 32000, 60000, 32000, 2, 4, 4, 4, 4, 2, 0, -3, SBR_SWITCH_LRC, 3 }, /* lowest range (multichannel rear) */
{ 60000, 80000, 32000, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* lowest range (multichannel rear) */ { CODEC_AAC, 60000, 80000, 32000, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* lowest range (multichannel rear) */
{ 80000,112000, 32000, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* low range */ { CODEC_AAC, 80000,112000, 32000, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* low range */
{ 112000,144000, 32000, 2, 11,11,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* SBR sweet spot */ { CODEC_AAC, 112000,144000, 32000, 2, 11,11,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* SBR sweet spot */
{ 144000,256001, 32000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* backwards compatible */ { CODEC_AAC, 144000,256001, 32000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* backwards compatible */
/* 44.1/88.2 kHz dual rate */ /* placebo settings */ /* 44.1/88.2 kHz dual rate */ /* placebo settings */
{ 32000, 60000, 44100, 2, 4, 4, 4, 4, 2, 0, -3, SBR_SWITCH_LRC, 3 }, /* lowest range (multichannel rear) */ { CODEC_AAC, 32000, 60000, 44100, 2, 4, 4, 4, 4, 2, 0, -3, SBR_SWITCH_LRC, 3 }, /* lowest range (multichannel rear) */
{ 60000, 80000, 44100, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* lowest range (multichannel rear) */ { CODEC_AAC, 60000, 80000, 44100, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* lowest range (multichannel rear) */
{ 80000,112000, 44100, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* low range */ { CODEC_AAC, 80000,112000, 44100, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* low range */
{ 112000,144000, 44100, 2, 11,11,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* SBR sweet spot */ { CODEC_AAC, 112000,144000, 44100, 2, 11,11,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* SBR sweet spot */
{ 144000,256001, 44100, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* backwards compatible */ { CODEC_AAC, 144000,256001, 44100, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* backwards compatible */
/* 48/96 kHz dual rate */ /* not yet finally tuned */ /* 48/96 kHz dual rate */ /* not yet finally tuned */
{ 36000, 60000, 48000, 2, 4, 4, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, 3 }, /* lowest range (multichannel rear) */ { CODEC_AAC, 36000, 60000, 48000, 2, 4, 4, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, 3 }, /* lowest range (multichannel rear) */
{ 60000, 80000, 48000, 2, 7, 7, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 64 */ { CODEC_AAC, 60000, 80000, 48000, 2, 7, 7, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 64 */
{ 80000,112000, 48000, 2, 9, 9,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 96 */ { CODEC_AAC, 80000,112000, 48000, 2, 9, 9,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 96 */
{ 112000,144000, 48000, 2, 11,11,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 128 */ { CODEC_AAC, 112000,144000, 48000, 2, 11,11,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 128 */
{ 144000,256001, 48000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 192 */ { CODEC_AAC, 144000,256001, 48000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 192 */
/** AAC LOW DELAY SECTION **/ /** AAC LOW DELAY SECTION **/
/*** mono ***/
/* 16/32 kHz dual rate not yet tuned ->alb copied from non LD tables*/
{ CODEC_AACLD, 16000, 18000, 16000, 1, 4, 5, 9, 7, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s wrr: tuned */
{ CODEC_AACLD, 18000, 22000, 16000, 1, 7, 7,12,12, 1, 6, 9, SBR_MONO, 3 }, /* nominal: 20 kbit/s wrr: tuned */
{ CODEC_AACLD, 22000, 28000, 16000, 1, 6, 6, 9, 9, 2, 3, 6, SBR_MONO, 3 }, /* nominal: 24 kbit/s wrr: tuned */
{ CODEC_AACLD, 28000, 36000, 16000, 1, 8, 8,12, 7, 2, 9,12, SBR_MONO, 3 }, /* jgr: special */ /* wrr: tuned */
{ CODEC_AACLD, 36000, 44000, 16000, 1, 10,14,12,13, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */
{ CODEC_AACLD, 44000, 64001, 16000, 1, 11,14,13,13, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */
/* 22.05/44.1 kHz dual rate */ /* 22.05/44.1 kHz dual rate */
{ 18000, 22000, 22050, 1, 4, 4, 5, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ { CODEC_AACLD, 18000, 22000, 22050, 1, 4, 4, 5, 5, 2, 0, 6, SBR_MONO, 3 }, /* nominal: 20 kbit/s */
{ 22000, 28000, 22050, 1, 4, 4, 6, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ { CODEC_AACLD, 22000, 28000, 22050, 1, 5, 5, 6, 6, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */
{ 28000, 36000, 22050, 1, 7, 8, 8, 8, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ { CODEC_AACLD, 28000, 36000, 22050, 1, 7, 8, 8, 8, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */
{ 36000, 44000, 22050, 1, 9, 9, 9, 9, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ { CODEC_AACLD, 36000, 44000, 22050, 1, 9, 9, 9, 9, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */
{ 44000, 52000, 22050, 1, 11,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ { CODEC_AACLD, 44000, 52000, 22050, 1, 12,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */
{ 52000, 64001, 22050, 1, 12,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 56 kbit/s */ { CODEC_AACLD, 52000, 64001, 22050, 1, 13,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 56 kbit/s */
/* 24/48 kHz dual rate */ /* 24/48 kHz dual rate */
{ 20000, 22000, 24000, 1, 4, 4, 5, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */ { CODEC_AACLD, 20000, 22000, 24000, 1, 4, 1, 8, 4, 2, 3, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */
{ 22000, 28000, 24000, 1, 4, 4, 6, 5, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 24 kbit/s */ { CODEC_AACLD, 22000, 28000, 24000, 1, 3, 8, 8, 7, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 24 kbit/s */
{ 28000, 36000, 24000, 1, 6, 8, 8, 8, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */ { CODEC_AACLD, 28000, 36000, 24000, 1, 4, 8, 8, 7, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */
{ 36000, 44000, 24000, 1, 8, 9, 9, 9, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */ { CODEC_AACLD, 36000, 56000, 24000, 1, 8, 9, 9, 9, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */
{ 44000, 52000, 24000, 1, 12,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */ { CODEC_AACLD, 56000, 64001, 24000, 1, 13,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 kbit/s */
{ 52000, 64001, 24000, 1, 13,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 48 kbit/s */
/* 32/64 kHz dual rate */ /* placebo settings */ /*jgr: new, copy from CODEC_AAC */
{ CODEC_AACLD, 24000, 36000, 32000, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3 }, /* lowest range */
{ CODEC_AACLD, 36000, 60000, 32000, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2 }, /* lowest range */
{ CODEC_AACLD, 60000, 72000, 32000, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1 }, /* low range */
{ CODEC_AACLD, 72000,100000, 32000, 1, 11,11,10,10, 2, 0, 3, SBR_MONO, 1 }, /* SBR sweet spot */
{ CODEC_AACLD, 100000,160001, 32000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* backwards compatible */
/* 44/88 kHz dual rate */ /* not yet finally tuned */
{ CODEC_AACLD, 36000, 60000, 44100, 1, 8, 7, 6, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 40 */
{ CODEC_AACLD, 60000, 72000, 44100, 1, 9, 9,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 */
{ CODEC_AACLD, 72000,100000, 44100, 1, 11,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 80 */
{ CODEC_AACLD, 100000,160001, 44100, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */
/* 48/96 kHz dual rate */ /* 32 and 40kbps line tuned for dual-rate SBR */
{ CODEC_AACLD, 36000, 60000, 48000, 1, 8, 7, 6, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 40 */
{ CODEC_AACLD, 60000, 72000, 48000, 1, 9, 9,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 */
{ CODEC_AACLD, 72000,100000, 48000, 1, 11,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 80 */
{ CODEC_AACLD, 100000,160001, 48000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */
/*** stereo ***/
/* 16/32 kHz dual rate not yet tuned ->alb copied from non LD tables*/
{ CODEC_AACLD, 32000, 36000, 16000, 2, 10, 9,12,11, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */
{ CODEC_AACLD, 36000, 44000, 16000, 2, 13,13,13,13, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */
{ CODEC_AACLD, 44000, 52000, 16000, 2, 10, 9,11, 9, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* tune12 nominal: 48 kbit/s */
{ CODEC_AACLD, 52000, 60000, 16000, 2, 14,14,13,13, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */
{ CODEC_AACLD, 60000, 76000, 16000, 2, 14,14,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */
{ CODEC_AACLD, 76000,128001, 16000, 2, 14,14,13,13, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */
/* 22.05/44.1 kHz dual rate */ /* 22.05/44.1 kHz dual rate */
{ 32000, 36000, 22050, 2, 5, 4, 7, 6, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ { CODEC_AACLD, 32000, 36000, 22050, 2, 5, 4, 7, 6, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */
{ 36000, 44000, 22050, 2, 5, 8, 8, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ { CODEC_AACLD, 36000, 44000, 22050, 2, 5, 8, 8, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */
{ 44000, 52000, 22050, 2, 7,10, 8, 8, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ { CODEC_AACLD, 44000, 52000, 22050, 2, 7,10, 8, 8, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */
{ 52000, 60000, 22050, 2, 9,11, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ { CODEC_AACLD, 52000, 60000, 22050, 2, 9,11, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */
{ 60000, 76000, 22050, 2, 10,12,10,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ { CODEC_AACLD, 60000, 76000, 22050, 2, 10,12,10,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */
{ 76000, 82000, 22050, 2, 12,12,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ { CODEC_AACLD, 76000, 82000, 22050, 2, 12,12,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */
{ 82000,128001, 22050, 2, 13,12,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ { CODEC_AACLD, 82000,128001, 22050, 2, 13,12,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */
/* 24/48 kHz dual rate */ /* 24/48 kHz dual rate */
{ 32000, 36000, 24000, 2, 5, 4, 7, 6, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */ { CODEC_AACLD, 32000, 36000, 24000, 2, 5, 4, 7, 6, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 32 kbit/s */
{ 36000, 44000, 24000, 2, 4, 8, 8, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */ { CODEC_AACLD, 36000, 44000, 24000, 2, 4, 8, 8, 8, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 40 kbit/s */
{ 44000, 52000, 24000, 2, 6,10, 8, 8, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */ { CODEC_AACLD, 44000, 52000, 24000, 2, 6,10, 8, 8, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 48 kbit/s */
{ 52000, 60000, 24000, 2, 9,11, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */ { CODEC_AACLD, 52000, 60000, 24000, 2, 9,11, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, 1 }, /* nominal: 56 kbit/s */
{ 60000, 76000, 24000, 2, 11,12,10,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */ { CODEC_AACLD, 60000, 76000, 24000, 2, 11,12,10,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 64 kbit/s */
{ 76000, 88000, 24000, 2, 12,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */ { CODEC_AACLD, 76000, 88000, 24000, 2, 12,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 80 kbit/s */
{ 88000,128001, 24000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 92 kbit/s */ { CODEC_AACLD, 88000,128001, 24000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 92 kbit/s */
/* 32/64 kHz dual rate */ /* placebo settings */ /*jgr: new, copy from CODEC_AAC */
{ CODEC_AACLD, 60000, 80000, 32000, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* lowest range (multichannel rear) */
{ CODEC_AACLD, 80000,112000, 32000, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* low range */
{ CODEC_AACLD, 112000,144000, 32000, 2, 11,11,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* SBR sweet spot */
{ CODEC_AACLD, 144000,256001, 32000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* backwards compatible */
/* 44.1/88.2 kHz dual rate */ /* placebo settings */ /*wrr: new, copy from CODEC_AAC */
{ CODEC_AACLD, 60000, 80000, 44100, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, 2 }, /* lowest range (multichannel rear) */
{ CODEC_AACLD, 80000,112000, 44100, 2, 10,10, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* hlm 11-08-29 */
{ CODEC_AACLD, 112000,144000, 44100, 2, 12,12,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* hlm 11-08-29 */
{ CODEC_AACLD, 144000,256001, 44100, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* backwards compatible */
/* 48/96 kHz dual rate */ /* not yet finally tuned */ /*wrr: new, copy from CODEC_AAC */
{ CODEC_AACLD, 60000, 80000, 48000, 2, 7, 7,10,10, 2, 0, -3, SBR_SWITCH_LRC, 2 }, /* nominal: 64 */
{ CODEC_AACLD, 80000,112000, 48000, 2, 9, 9,10,10, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 96 */
{ CODEC_AACLD, 112000,144000, 48000, 2, 11,11,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* nominal: 128 */
{ CODEC_AACLD, 144000,176000, 48000, 2, 12,12,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* hlm 09-10-19 */
{ CODEC_AACLD, 176000,256001, 48000, 2, 13,13,11,11, 3, 0, -3, SBR_LEFT_RIGHT, 1 }, /* hlm 09-10-19 */
}; };
const int sbrTuningTableSize = sizeof(sbrTuningTable)/sizeof(sbrTuningTable[0]);
const psTuningTable_t psTuningTable[4] = const psTuningTable_t psTuningTable[4] =
{ {
{ 8000, 22000, PSENC_STEREO_BANDS_10, PSENC_NENV_1, FL2FXCONST_DBL(3.0f/4.0f) }, { 8000, 22000, PSENC_STEREO_BANDS_10, PSENC_NENV_1, FL2FXCONST_DBL(3.0f/4.0f) },
......
...@@ -118,13 +118,8 @@ extern const UCHAR v_Huff_NoiseLevelL11T[63]; ...@@ -118,13 +118,8 @@ extern const UCHAR v_Huff_NoiseLevelL11T[63];
extern const INT bookSbrNoiseBalanceC11T[25]; extern const INT bookSbrNoiseBalanceC11T[25];
extern const UCHAR bookSbrNoiseBalanceL11T[25]; extern const UCHAR bookSbrNoiseBalanceL11T[25];
#define SBRENC_AACLC_TUNING_SIZE 124 extern const sbrTuningTable_t sbrTuningTable[];
#define SBRENC_AACELD_TUNING_SIZE (26) extern const int sbrTuningTableSize;
#define SBRENC_AACELD2_TUNING_SIZE (26)
#define SBRENC_TUNING_SIZE (SBRENC_AACLC_TUNING_SIZE + SBRENC_AACELD_TUNING_SIZE)
extern const sbrTuningTable_t sbrTuningTable[SBRENC_TUNING_SIZE];
extern const psTuningTable_t psTuningTable[4]; extern const psTuningTable_t psTuningTable[4];
......
...@@ -84,6 +84,7 @@ amm-info@iis.fraunhofer.de ...@@ -84,6 +84,7 @@ amm-info@iis.fraunhofer.de
/*! /*!
\file \file
\brief frequency scale \brief frequency scale
\author Tobias Chalupka
*/ */
#include "sbrenc_freq_sca.h" #include "sbrenc_freq_sca.h"
...@@ -92,10 +93,10 @@ amm-info@iis.fraunhofer.de ...@@ -92,10 +93,10 @@ amm-info@iis.fraunhofer.de
#include "genericStds.h" #include "genericStds.h"
/* StartFreq */ /* StartFreq */
static INT getStartFreq(INT fs, const INT start_freq); static INT getStartFreq(INT fsCore, const INT start_freq);
/* StopFreq */ /* StopFreq */
static INT getStopFreq(INT fs, const INT stop_freq, const INT noChannels); static INT getStopFreq(INT fsCore, const INT stop_freq);
static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor); static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor);
static void CalcBands(INT * diff, INT start , INT stop , INT num_bands); static void CalcBands(INT * diff, INT start , INT stop , INT num_bands);
...@@ -115,7 +116,7 @@ static void cumSum(INT start_value, INT* diff, INT length, UCHAR *start_adress) ...@@ -115,7 +116,7 @@ static void cumSum(INT start_value, INT* diff, INT length, UCHAR *start_adress)
*******************************************************************************/ *******************************************************************************/
INT INT
FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT QMFbands, INT fs) FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT fsCore)
{ {
INT result; INT result;
...@@ -123,9 +124,9 @@ FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT QMFbands, INT fs) ...@@ -123,9 +124,9 @@ FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT QMFbands, INT fs)
return -1; return -1;
} }
/* Update startFreq struct */ /* Update startFreq struct */
result = getStartFreq(fs, startFreq); result = getStartFreq(fsCore, startFreq);
result = (result*fs/QMFbands+1)>>1; result = (result*(fsCore>>5)+1)>>1; /* (result*fsSBR/QMFbands+1)>>1; */
return (result); return (result);
...@@ -141,17 +142,16 @@ FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT QMFbands, INT fs) ...@@ -141,17 +142,16 @@ FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT QMFbands, INT fs)
Return: Return:
*******************************************************************************/ *******************************************************************************/
INT FDKsbrEnc_getSbrStopFreqRAW (INT stopFreq, INT QMFbands, INT fs) INT FDKsbrEnc_getSbrStopFreqRAW (INT stopFreq, INT fsCore)
{ {
INT result; INT result;
if ( stopFreq < 0 || stopFreq > 13) if ( stopFreq < 0 || stopFreq > 13)
return -1; return -1;
/* Uppdate stopFreq struct */ /* Uppdate stopFreq struct */
result = getStopFreq( fs, stopFreq, QMFbands); result = getStopFreq(fsCore, stopFreq);
result = (result*fs/QMFbands+1)>>1; result = (result*(fsCore>>5)+1)>>1; /* (result*fsSBR/QMFbands+1)>>1; */
return (result); return (result);
} /* End getSbrStopFreq */ } /* End getSbrStopFreq */
...@@ -162,69 +162,73 @@ INT FDKsbrEnc_getSbrStopFreqRAW (INT stopFreq, INT QMFbands, INT fs) ...@@ -162,69 +162,73 @@ INT FDKsbrEnc_getSbrStopFreqRAW (INT stopFreq, INT QMFbands, INT fs)
******************************************************************************* *******************************************************************************
Description: Description:
Arguments: Arguments: fsCore - core sampling rate
Return: Return:
*******************************************************************************/ *******************************************************************************/
static INT static INT
getStartFreq(INT fs, const INT start_freq) getStartFreq(INT fsCore, const INT start_freq)
{ {
INT k0_min; INT k0_min;
switch(fs){ switch(fsCore){
case 16000: k0_min = 24; case 8000: k0_min = 24; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */
break; break;
case 22050: k0_min = 17; case 11025: k0_min = 17; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */
break; break;
case 24000: k0_min = 16; case 12000: k0_min = 16; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */
break; break;
case 32000: k0_min = 16; case 16000: k0_min = 16; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */
break; break;
case 44100: k0_min = 12; case 22050: k0_min = 12; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */
break; break;
case 48000: k0_min = 11; case 24000: k0_min = 11; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */
break; break;
case 64000: k0_min = 10; case 32000: k0_min = 10; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
break; break;
case 88200: k0_min = 7; case 44100: k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
break; break;
case 96000: k0_min = 7; case 48000: k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
break;
case 96000: k0_min = 3; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */
break; break;
default: default:
k0_min=11; /* illegal fs */ k0_min=11; /* illegal fs */
} }
switch (fs) { switch (fsCore) {
case 16000: case 8000:
{ {
INT v_offset[]= {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}; INT v_offset[]= {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
return (k0_min + v_offset[start_freq]); return (k0_min + v_offset[start_freq]);
} }
case 22050: case 11025:
{ {
INT v_offset[]= {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13}; INT v_offset[]= {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13};
return (k0_min + v_offset[start_freq]); return (k0_min + v_offset[start_freq]);
} }
case 24000: case 12000:
{ {
INT v_offset[]= {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}; INT v_offset[]= {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16};
return (k0_min + v_offset[start_freq]); return (k0_min + v_offset[start_freq]);
} }
case 32000: case 16000:
{ {
INT v_offset[]= {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}; INT v_offset[]= {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16};
return (k0_min + v_offset[start_freq]); return (k0_min + v_offset[start_freq]);
} }
case 44100: case 22050:
case 48000: case 24000:
case 64000: case 32000:
{ {
INT v_offset[]= {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20}; INT v_offset[]= {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20};
return (k0_min + v_offset[start_freq]); return (k0_min + v_offset[start_freq]);
} }
case 88200: case 44100:
case 48000:
case 96000: case 96000:
{ {
INT v_offset[]= {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24}; INT v_offset[]= {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24};
...@@ -249,13 +253,12 @@ getStartFreq(INT fs, const INT start_freq) ...@@ -249,13 +253,12 @@ getStartFreq(INT fs, const INT start_freq)
Return: Return:
*******************************************************************************/ *******************************************************************************/
static INT static INT
getStopFreq(INT fs, const INT stop_freq, const INT noChannels) getStopFreq(INT fsCore, const INT stop_freq)
{ {
INT result,i; INT result,i;
INT k1_min; INT k1_min;
INT v_dstop[13]; INT v_dstop[13];
INT *v_stop_freq = NULL; INT *v_stop_freq = NULL;
INT v_stop_freq_16[14] = {48,49,50,51,52,54,55,56,57,59,60,61,63,64}; INT v_stop_freq_16[14] = {48,49,50,51,52,54,55,56,57,59,60,61,63,64};
INT v_stop_freq_22[14] = {35,37,38,40,42,44,46,48,51,53,56,58,61,64}; INT v_stop_freq_22[14] = {35,37,38,40,42,44,46,48,51,53,56,58,61,64};
...@@ -266,40 +269,45 @@ getStopFreq(INT fs, const INT stop_freq, const INT noChannels) ...@@ -266,40 +269,45 @@ getStopFreq(INT fs, const INT stop_freq, const INT noChannels)
INT v_stop_freq_64[14] = {20,22,24,26,29,31,34,37,41,45,49,54,59,64}; INT v_stop_freq_64[14] = {20,22,24,26,29,31,34,37,41,45,49,54,59,64};
INT v_stop_freq_88[14] = {15,17,19,21,23,26,29,33,37,41,46,51,57,64}; INT v_stop_freq_88[14] = {15,17,19,21,23,26,29,33,37,41,46,51,57,64};
INT v_stop_freq_96[14] = {13,15,17,19,21,24,27,31,35,39,44,50,57,64}; INT v_stop_freq_96[14] = {13,15,17,19,21,24,27,31,35,39,44,50,57,64};
INT v_stop_freq_192[14] = {7, 8,10,12,14,16,19,23,27,32,38,46,54,64};
switch(fs){ switch(fsCore){
case 16000: k1_min = 48; case 8000: k1_min = 48;
v_stop_freq =v_stop_freq_16; v_stop_freq =v_stop_freq_16;
break; break;
case 22050: k1_min = 35; case 11025: k1_min = 35;
v_stop_freq =v_stop_freq_22; v_stop_freq =v_stop_freq_22;
break; break;
case 24000: k1_min = 32; case 12000: k1_min = 32;
v_stop_freq =v_stop_freq_24; v_stop_freq =v_stop_freq_24;
break; break;
case 32000: k1_min = 32; case 16000: k1_min = 32;
v_stop_freq =v_stop_freq_32; v_stop_freq =v_stop_freq_32;
break; break;
case 44100: k1_min = 23; case 22050: k1_min = 23;
v_stop_freq =v_stop_freq_44; v_stop_freq =v_stop_freq_44;
break; break;
case 48000: k1_min = 21; case 24000: k1_min = 21;
v_stop_freq =v_stop_freq_48; v_stop_freq =v_stop_freq_48;
break; break;
case 64000: k1_min = 20; case 32000: k1_min = 20;
v_stop_freq =v_stop_freq_64; v_stop_freq =v_stop_freq_64;
break; break;
case 88200: k1_min = 15; case 44100: k1_min = 15;
v_stop_freq =v_stop_freq_88; v_stop_freq =v_stop_freq_88;
break; break;
case 96000: k1_min = 13; case 48000: k1_min = 13;
v_stop_freq =v_stop_freq_96; v_stop_freq =v_stop_freq_96;
break; break;
case 96000: k1_min = 7;
v_stop_freq =v_stop_freq_192;
break;
default: default:
k1_min = 21; /* illegal fs */ k1_min = 21; /* illegal fs */
} }
/* if no valid core samplingrate is used this loop produces
a segfault, because v_stop_freq is not initialized */
/* Ensure increasing bandwidth */ /* Ensure increasing bandwidth */
for(i = 0; i <= 12; i++) { for(i = 0; i <= 12; i++) {
v_dstop[i] = v_stop_freq[i+1] - v_stop_freq[i]; v_dstop[i] = v_stop_freq[i+1] - v_stop_freq[i];
...@@ -322,34 +330,41 @@ getStopFreq(INT fs, const INT stop_freq, const INT noChannels) ...@@ -322,34 +330,41 @@ getStopFreq(INT fs, const INT stop_freq, const INT noChannels)
******************************************************************************* *******************************************************************************
Description: Description:
Arguments: Arguments: srSbr SBR sampling freqency
srCore AAC core sampling freqency
noChannels Number of QMF channels
startFreq SBR start frequency in QMF bands
stopFreq SBR start frequency in QMF bands
Return: *k0 Output parameter
*k2 Output parameter
Return: Error code (0 is OK)
*******************************************************************************/ *******************************************************************************/
INT INT
FDKsbrEnc_FindStartAndStopBand(const INT samplingFreq, FDKsbrEnc_FindStartAndStopBand(
const INT noChannels, const INT srSbr,
const INT startFreq, const INT srCore,
const INT stopFreq, const INT noChannels,
const SR_MODE sampleRateMode, const INT startFreq,
INT *k0, const INT stopFreq,
INT *k2) INT *k0,
INT *k2
)
{ {
/* Update startFreq struct */ /* Update startFreq struct */
*k0 = getStartFreq(samplingFreq, startFreq); *k0 = getStartFreq(srCore, startFreq);
/* Test if start freq is outside corecoder range */ /* Test if start freq is outside corecoder range */
if( ( sampleRateMode == 1 ) && if( srSbr*noChannels < *k0 * srCore ) {
( samplingFreq*noChannels <
2**k0 * samplingFreq) ) {
return (1); /* raise the cross-over frequency and/or lower the number return (1); /* raise the cross-over frequency and/or lower the number
of target bands per octave (or lower the sampling frequency) */ of target bands per octave (or lower the sampling frequency) */
} }
/*Update stopFreq struct */ /*Update stopFreq struct */
if ( stopFreq < 14 ) { if ( stopFreq < 14 ) {
*k2 = getStopFreq(samplingFreq, stopFreq, noChannels); *k2 = getStopFreq(srCore, stopFreq);
} else if( stopFreq == 14 ) { } else if( stopFreq == 14 ) {
*k2 = 2 * *k0; *k2 = 2 * *k0;
} else { } else {
...@@ -364,10 +379,10 @@ FDKsbrEnc_FindStartAndStopBand(const INT samplingFreq, ...@@ -364,10 +379,10 @@ FDKsbrEnc_FindStartAndStopBand(const INT samplingFreq,
/* Test for invalid k0 k2 combinations */ /* Test for invalid k0 k2 combinations */
if ( (samplingFreq == 44100) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS44100 ) ) if ( (srCore == 22050) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS44100 ) )
return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for fs=44.1kHz */ return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for fs=44.1kHz */
if ( (samplingFreq >= 48000) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS48000 ) ) if ( (srCore >= 24000) && ( (*k2 - *k0) > MAX_FREQ_COEFFS_FS48000 ) )
return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for fs>=48kHz */ return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for fs>=48kHz */
if ((*k2 - *k0) > MAX_FREQ_COEFFS) if ((*k2 - *k0) > MAX_FREQ_COEFFS)
...@@ -390,15 +405,19 @@ FDKsbrEnc_FindStartAndStopBand(const INT samplingFreq, ...@@ -390,15 +405,19 @@ FDKsbrEnc_FindStartAndStopBand(const INT samplingFreq,
Return: Return:
*******************************************************************************/ *******************************************************************************/
INT INT
FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, FDKsbrEnc_UpdateFreqScale(
const INT k0, const INT k2, UCHAR *v_k_master,
const INT freqScale, INT *h_num_bands,
const INT alterScale) const INT k0,
const INT k2,
const INT freqScale,
const INT alterScale
)
{ {
INT b_p_o = 0; /* bands_per_octave */ INT b_p_o = 0; /* bands_per_octave */
FIXP_DBL warp = FL2FXCONST_DBL(0.0f); FIXP_DBL warp = FL2FXCONST_DBL(0.0f);
INT dk = 0; INT dk = 0;
/* Internal variables */ /* Internal variables */
...@@ -426,7 +445,7 @@ FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, ...@@ -426,7 +445,7 @@ FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands,
warp = FL2FXCONST_DBL(1.0f/2.6f); /* 1.0/(1.3*2.0); */ warp = FL2FXCONST_DBL(1.0f/2.6f); /* 1.0/(1.3*2.0); */
if(4*k2 >= 9*k0) /*two or more regions*/ if(4*k2 >= 9*k0) /*two or more regions (how many times the basis band is copied)*/
{ {
k1=2*k0; k1=2*k0;
...@@ -592,30 +611,31 @@ modifyBands(INT max_band_previous, INT * diff, INT length) ...@@ -592,30 +611,31 @@ modifyBands(INT max_band_previous, INT * diff, INT length)
******************************************************************************* *******************************************************************************
Description: Description:
Arguments: Arguments:
Return: Return:
*******************************************************************************/ *******************************************************************************/
INT INT
FDKsbrEnc_UpdateHiRes(UCHAR *h_hires, INT *num_hires,UCHAR * v_k_master, FDKsbrEnc_UpdateHiRes(
INT num_master , INT *xover_band, SR_MODE drOrSr, UCHAR *h_hires,
INT noQMFChannels) INT *num_hires,
UCHAR *v_k_master,
INT num_master,
INT *xover_band
)
{ {
INT i; INT i;
INT divider;
INT max1,max2; INT max1,max2;
/* Check if we use a Dual rate => diver=2 else 1 */ if( (v_k_master[*xover_band] > 32 ) || /* v_k_master[*xover_band] > noQMFChannels(dualRate)/divider */
divider = (drOrSr == DUAL_RATE) ? 2 : 1;
if( (v_k_master[*xover_band] > (noQMFChannels/divider) ) ||
( *xover_band > num_master ) ) { ( *xover_band > num_master ) ) {
/* xover_band error, too big for this startFreq. Will be clipped */ /* xover_band error, too big for this startFreq. Will be clipped */
/* Calculate maximum value for xover_band */ /* Calculate maximum value for xover_band */
max1=0; max1=0;
max2=num_master; max2=num_master;
while( (v_k_master[max1+1] < (noQMFChannels/divider)) && while( (v_k_master[max1+1] < 32 ) && /* noQMFChannels(dualRate)/divider */
( (max1+1) < max2) ) ( (max1+1) < max2) )
{ {
max1++; max1++;
......
...@@ -96,34 +96,42 @@ amm-info@iis.fraunhofer.de ...@@ -96,34 +96,42 @@ amm-info@iis.fraunhofer.de
INT INT
FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, FDKsbrEnc_UpdateFreqScale(
const INT k0, const INT k2, UCHAR *v_k_master,
const INT freq_scale, INT *h_num_bands,
const INT alter_scale); const INT k0,
const INT k2,
const INT freq_scale,
const INT alter_scale
);
INT INT
FDKsbrEnc_UpdateHiRes(UCHAR *h_hires, FDKsbrEnc_UpdateHiRes(
INT *num_hires, UCHAR *h_hires,
UCHAR *v_k_master, INT *num_hires,
INT num_master , UCHAR *v_k_master,
INT *xover_band, INT num_master,
SR_MODE drOrSr, INT *xover_band
INT noQMFChannels); );
void FDKsbrEnc_UpdateLoRes(UCHAR * v_lores, void FDKsbrEnc_UpdateLoRes(
INT *num_lores, UCHAR *v_lores,
UCHAR * v_hires, INT *num_lores,
INT num_hires); UCHAR *v_hires,
INT num_hires
);
INT INT
FDKsbrEnc_FindStartAndStopBand(const INT samplingFreq, FDKsbrEnc_FindStartAndStopBand(
const INT noChannels, const INT srSbr,
const INT startFreq, const INT srCore,
const INT stop_freq, const INT noChannels,
const SR_MODE sampleRateMode, const INT startFreq,
INT *k0, const INT stop_freq,
INT *k2); INT *k0,
INT *k2
INT FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT QMFbands, INT fs ); );
INT FDKsbrEnc_getSbrStopFreqRAW (INT stopFreq, INT QMFbands, INT fs);
INT FDKsbrEnc_getSbrStartFreqRAW (INT startFreq, INT fsCore);
INT FDKsbrEnc_getSbrStopFreqRAW (INT stopFreq, INT fsCore);
#endif #endif
...@@ -303,8 +303,6 @@ FDKsbrEnc_CalculateTonalityQuotas( HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< H ...@@ -303,8 +303,6 @@ FDKsbrEnc_CalculateTonalityQuotas( HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< H
} }
} }
FDK_ASSERT(noEstPerFrame == 2);
C_ALLOC_SCRATCH_END(realBuf, FIXP_DBL, 2*BAND_V_SIZE*NUM_V_COMBINE); C_ALLOC_SCRATCH_END(realBuf, FIXP_DBL, 2*BAND_V_SIZE*NUM_V_COMBINE);
C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1); C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment