AAC/SBR encoder improvements
* AAC-Encoder - AAC-ELD core encoder audio quality tuning. Update tuning tables, configure bitreservoir size and adapt afterburner iteration value. Modified file(s): libAACenc/src/aacenc.h libAACenc/src/aacenc_lib.cpp libAACenc/src/adj_thr.cpp libAACenc/src/adj_thr.h libAACenc/src/adj_thr_data.h libAACenc/src/bandwidth.cpp libAACenc/src/pnsparam.cpp libAACenc/src/qc_main.cpp - Introduze dead zone quantizer for ELD to improve audio quality at certain configurations. Modified file(s): libAACenc/src/aacenc_lib.cpp libAACenc/src/adj_thr.cpp libAACenc/src/adj_thr.h libAACenc/src/qc_data.h libAACenc/src/qc_main.cpp libAACenc/src/quantize.cpp libAACenc/src/quantize.h libAACenc/src/sf_estim.cpp libAACenc/src/sf_estim.h - Revise TNS module to improve ELD audio quality. - Use new window function and separate prediction gain according TNS filters. - Add missing memory initilization to TNS configuration. Modified file(s): libAACenc/src/aacenc_lib.cpp libAACenc/src/aacenc_tns.cpp libAACenc/src/aacenc_tns.h libAACenc/src/psy_main.cpp libAACenc/src/tns_func.h * SBR-Encoder - Revise frequency resolution calculation and handle differently depending on number of envelopes and split frames decision. - Add and adjust ELD SBR tuning tables. Modified file(s): libSBRenc/include/sbr_encoder.h libSBRenc/src/bit_sbr.h libSBRenc/src/env_est.cpp libSBRenc/src/fram_gen.cpp libSBRenc/src/fram_gen.h libSBRenc/src/mh_det.cpp libSBRenc/src/sbr_def.h libSBRenc/src/sbr_encoder.cpp libSBRenc/src/sbr_rom.cpp libSBRenc/src/tran_det.cpp - Replace ELD transient detector with fast implementation. Modified file(s): libSBRenc/src/env_est.cpp libSBRenc/src/env_est.h libSBRenc/src/fram_gen.cpp libSBRenc/src/sbr_def.h libSBRenc/src/sbr_encoder.cpp libSBRenc/src/tran_det.cpp libSBRenc/src/tran_det.h * FDK-Library - Introduce generic compare function in tools library. Modified file(s): libFDK/include/fixpoint_math.h libFDK/src/FDK_core.cpp * SBR-Encoder - Revise ELD frame splitter to improve bit distribution. Modified file(s): libSBRenc/include/sbr_encoder.h libSBRenc/src/bit_sbr.h libSBRenc/src/env_est.cpp libSBRenc/src/fram_gen.cpp libSBRenc/src/fram_gen.h libSBRenc/src/sbr_encoder.cpp libSBRenc/src/tran_det.cpp libSBRenc/src/tran_det.h - Configure amplitude resolution according the tonality of the audio signal. Modified file(s): libSBRenc/include/sbr_encoder.h libSBRenc/src/bit_sbr.h libSBRenc/src/env_est.cpp libSBRenc/src/nf_est.cpp libSBRenc/src/nf_est.h libSBRenc/src/sbr_def.h libSBRenc/src/sbr_encoder.cpp libSBRenc/src/ton_corr.cpp libSBRenc/src/ton_corr.h libSBRenc/src/tran_det.cpp libSBRenc/src/tran_det.h Change-Id: Ie0672b989a06ee63b50240616b8d1d4b790b6cb2
This commit is contained in:
parent
4834f01bdf
commit
46ba3676b8
@ -98,6 +98,11 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
#include "sbr_encoder.h"
|
||||
|
||||
#define BITRES_MAX_LD 4000
|
||||
#define BITRES_MIN_LD 500
|
||||
#define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */
|
||||
#define BITRATE_MIN_LD 12000 /* Min assumed bitrate for bitres calculation */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -98,7 +98,7 @@ amm-info@iis.fraunhofer.de
|
||||
/* Encoder library info */
|
||||
#define AACENCODER_LIB_VL0 3
|
||||
#define AACENCODER_LIB_VL1 4
|
||||
#define AACENCODER_LIB_VL2 19
|
||||
#define AACENCODER_LIB_VL2 22
|
||||
#define AACENCODER_LIB_TITLE "AAC Encoder"
|
||||
#ifdef __ANDROID__
|
||||
#define AACENCODER_LIB_BUILD_DATE ""
|
||||
@ -813,11 +813,16 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
|
||||
switch ( hAacConfig->audioObjectType ) {
|
||||
case AOT_ER_AAC_LD:
|
||||
case AOT_ER_AAC_ELD:
|
||||
if (config->userBitrateMode==8) {
|
||||
hAacConfig->bitrateMode = 0;
|
||||
}
|
||||
if (config->userBitrateMode==0) {
|
||||
hAacConfig->bitreservoir = 100*config->nChannels; /* default, reduced bitreservoir */
|
||||
/* bitreservoir = (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes; */
|
||||
if ( isLowDelay(hAacConfig->audioObjectType) ) {
|
||||
INT bitreservoir;
|
||||
INT brPerChannel = hAacConfig->bitRate/hAacConfig->nChannels;
|
||||
brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
|
||||
FIXP_DBL slope = fDivNorm((brPerChannel-BITRATE_MIN_LD), BITRATE_MAX_LD-BITRATE_MIN_LD); /* calc slope for interpolation */
|
||||
bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD-BITRES_MIN_LD)) + BITRES_MIN_LD; /* interpolate */
|
||||
hAacConfig->bitreservoir = bitreservoir & ~7; /* align to bytes */
|
||||
}
|
||||
}
|
||||
if (hAacConfig->bitrateMode!=0) {
|
||||
return AACENC_INVALID_CONFIG;
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -95,13 +95,7 @@ amm-info@iis.fraunhofer.de
|
||||
#include "aacEnc_rom.h"
|
||||
#include "aacenc_tns.h"
|
||||
|
||||
enum {
|
||||
HIFILT = 0, /* index of higher filter */
|
||||
LOFILT = 1 /* index of lower filter */
|
||||
};
|
||||
|
||||
|
||||
#define FILTER_DIRECTION 0
|
||||
#define FILTER_DIRECTION 0 /* 0 = up, 1 = down */
|
||||
|
||||
static const FIXP_DBL acfWindowLong[12+3+1] = {
|
||||
0x7fffffff,0x7fb80000,0x7ee00000,0x7d780000,0x7b800000,0x78f80000,0x75e00000,0x72380000,
|
||||
@ -112,20 +106,6 @@ static const FIXP_DBL acfWindowShort[4+3+1] = {
|
||||
0x7fffffff,0x7e000000,0x78000000,0x6e000000,0x60000000,0x4e000000,0x38000000,0x1e000000
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
INT filterEnabled[MAX_NUM_OF_FILTERS];
|
||||
INT threshOn[MAX_NUM_OF_FILTERS]; /* min. prediction gain for using tns TABUL*/
|
||||
INT filterStartFreq[MAX_NUM_OF_FILTERS]; /* lowest freq for lpc TABUL*/
|
||||
INT tnsLimitOrder[MAX_NUM_OF_FILTERS]; /* Limit for TNS order TABUL*/
|
||||
INT tnsFilterDirection[MAX_NUM_OF_FILTERS]; /* Filtering direction, 0=up, 1=down TABUL */
|
||||
INT acfSplit[MAX_NUM_OF_FILTERS];
|
||||
FIXP_DBL tnsTimeResolution[MAX_NUM_OF_FILTERS]; /* TNS max. time resolution TABUL. Should be fract but MSVC won't compile then */
|
||||
INT seperateFiltersAllowed;
|
||||
|
||||
} TNS_PARAMETER_TABULATED;
|
||||
|
||||
|
||||
typedef struct{
|
||||
INT bitRateFrom[2]; /* noneSbr=0, useSbr=1 */
|
||||
INT bitRateTo[2]; /* noneSbr=0, useSbr=1 */
|
||||
@ -373,6 +353,7 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate,
|
||||
INT channels,
|
||||
INT blockType,
|
||||
INT granuleLength,
|
||||
INT isLowDelay,
|
||||
INT ldSbrPresent,
|
||||
TNS_CONFIG *tC,
|
||||
PSY_CONFIGURATION *pC,
|
||||
@ -385,6 +366,8 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate,
|
||||
if (channels <= 0)
|
||||
return (AAC_ENCODER_ERROR)1;
|
||||
|
||||
tC->isLowDelay = isLowDelay;
|
||||
|
||||
/* initialize TNS filter flag, order, and coefficient resolution (in bits per coeff) */
|
||||
tC->tnsActive = (active) ? TRUE : FALSE;
|
||||
tC->maxOrder = (blockType == SHORT_WINDOW) ? 5 : 12; /* maximum: 7, 20 */
|
||||
@ -450,27 +433,14 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate,
|
||||
const TNS_PARAMETER_TABULATED* pCfg = FDKaacEnc_GetTnsParam(bitRate, channels, ldSbrPresent);
|
||||
|
||||
if ( pCfg != NULL ) {
|
||||
|
||||
FDKmemcpy(&(tC->confTab), pCfg, sizeof(tC->confTab));
|
||||
|
||||
tC->lpcStartBand[HIFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[HIFILT], sampleRate, pC->sfbCnt, pC->sfbOffset);
|
||||
tC->lpcStartLine[HIFILT] = pC->sfbOffset[tC->lpcStartBand[HIFILT]];
|
||||
tC->lpcStartBand[LOFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[LOFILT], sampleRate, pC->sfbCnt, pC->sfbOffset);
|
||||
tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]];
|
||||
|
||||
tC->confTab.threshOn[HIFILT] = pCfg->threshOn[HIFILT];
|
||||
tC->confTab.threshOn[LOFILT] = pCfg->threshOn[LOFILT];
|
||||
|
||||
tC->confTab.tnsLimitOrder[HIFILT] = pCfg->tnsLimitOrder[HIFILT];
|
||||
tC->confTab.tnsLimitOrder[LOFILT] = pCfg->tnsLimitOrder[LOFILT];
|
||||
|
||||
tC->confTab.tnsFilterDirection[HIFILT] = pCfg->tnsFilterDirection[HIFILT];
|
||||
tC->confTab.tnsFilterDirection[LOFILT] = pCfg->tnsFilterDirection[LOFILT];
|
||||
|
||||
tC->confTab.acfSplit[HIFILT] = pCfg->acfSplit[HIFILT];
|
||||
tC->confTab.acfSplit[LOFILT] = pCfg->acfSplit[LOFILT];
|
||||
|
||||
tC->confTab.filterEnabled[HIFILT] = pCfg->filterEnabled[HIFILT];
|
||||
tC->confTab.filterEnabled[LOFILT] = pCfg->filterEnabled[LOFILT];
|
||||
tC->confTab.seperateFiltersAllowed = pCfg->seperateFiltersAllowed;
|
||||
|
||||
FDKaacEnc_CalcGaussWindow(tC->acfWindow[HIFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[HIFILT], TNS_TIMERES_SCALE);
|
||||
FDKaacEnc_CalcGaussWindow(tC->acfWindow[LOFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[LOFILT], TNS_TIMERES_SCALE);
|
||||
}
|
||||
@ -614,6 +584,7 @@ static inline FIXP_DBL FDKaacEnc_AutoCorrNormFac(
|
||||
|
||||
static void FDKaacEnc_MergedAutoCorrelation(
|
||||
const FIXP_DBL *spectrum,
|
||||
const INT isLowDelay,
|
||||
const FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER+3+1],
|
||||
const INT lpcStartLine[MAX_NUM_OF_FILTERS],
|
||||
const INT lpcStopLine,
|
||||
@ -633,6 +604,8 @@ static void FDKaacEnc_MergedAutoCorrelation(
|
||||
FDKmemclear(&_rxx1[0], sizeof(FIXP_DBL)*(maxOrder+1));
|
||||
FDKmemclear(&_rxx2[0], sizeof(FIXP_DBL)*(maxOrder+1));
|
||||
|
||||
idx0 = idx1 = idx2 = idx3 = idx4 = 0;
|
||||
|
||||
/* MDCT line indices separating the 1st, 2nd, 3rd, and 4th analysis quarters */
|
||||
if ( (acfSplit[LOFILT]==-1) || (acfSplit[HIFILT]==-1) ) {
|
||||
/* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the spectrum */
|
||||
@ -676,17 +649,27 @@ static void FDKaacEnc_MergedAutoCorrelation(
|
||||
/* compute energy normalization factors, i. e. 1/energy (saves some divisions) */
|
||||
if (rxx1_0 != FL2FXCONST_DBL(0.f))
|
||||
{
|
||||
INT sc_fac1 = -1;
|
||||
FIXP_DBL fac1 = FDKaacEnc_AutoCorrNormFac(rxx1_0, ((-2*sc1)+nsc1), &sc_fac1);
|
||||
_rxx1[0] = scaleValue(fMult(rxx1_0,fac1),sc_fac1);
|
||||
INT sc_fac1 = -1;
|
||||
FIXP_DBL fac1 = FDKaacEnc_AutoCorrNormFac(rxx1_0, ((-2*sc1)+nsc1), &sc_fac1);
|
||||
_rxx1[0] = scaleValue(fMult(rxx1_0,fac1),sc_fac1);
|
||||
|
||||
if (isLowDelay)
|
||||
{
|
||||
for (lag = 1; lag <= maxOrder; lag++) {
|
||||
/* compute energy-normalized and windowed autocorrelation values at this lag */
|
||||
FIXP_DBL x1 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1);
|
||||
_rxx1[lag] = fMult(scaleValue(fMult(x1,fac1),sc_fac1), acfWindow[LOFILT][lag]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (lag = 1; lag <= maxOrder; lag++) {
|
||||
if ((3 * lag) <= maxOrder + 3) {
|
||||
FIXP_DBL x1 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1);
|
||||
_rxx1[lag] = fMult(scaleValue(fMult(x1,fac1),sc_fac1), acfWindow[LOFILT][3*lag]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* auto corr over upper 3/4 of spectrum */
|
||||
@ -762,8 +745,12 @@ INT FDKaacEnc_TnsDetect(
|
||||
: &tnsData->dataRaw.Long.subBlockInfo;
|
||||
|
||||
tnsData->filtersMerged = FALSE;
|
||||
tsbi->tnsActive = FALSE;
|
||||
tsbi->predictionGain = 1000;
|
||||
|
||||
tsbi->tnsActive[HIFILT] = FALSE;
|
||||
tsbi->predictionGain[HIFILT] = 1000;
|
||||
tsbi->tnsActive[LOFILT] = FALSE;
|
||||
tsbi->predictionGain[LOFILT] = 1000;
|
||||
|
||||
tnsInfo->numOfFilters[subBlockNumber] = 0;
|
||||
tnsInfo->coefRes[subBlockNumber] = tC->coefRes;
|
||||
for (i = 0; i < tC->maxOrder; i++) {
|
||||
@ -779,6 +766,7 @@ INT FDKaacEnc_TnsDetect(
|
||||
|
||||
FDKaacEnc_MergedAutoCorrelation(
|
||||
spectrum,
|
||||
tC->isLowDelay,
|
||||
tC->acfWindow,
|
||||
tC->lpcStartLine,
|
||||
tC->lpcStopLine,
|
||||
@ -788,7 +776,7 @@ INT FDKaacEnc_TnsDetect(
|
||||
rxx2);
|
||||
|
||||
/* compute higher TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */
|
||||
tsbi->predictionGain = FDKaacEnc_AutoToParcor(rxx2, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT]);
|
||||
tsbi->predictionGain[HIFILT] = FDKaacEnc_AutoToParcor(rxx2, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT]);
|
||||
|
||||
/* non-linear quantization of TNS lattice coefficients with given resolution */
|
||||
FDKaacEnc_Parcor2Index(
|
||||
@ -815,9 +803,9 @@ INT FDKaacEnc_TnsDetect(
|
||||
tnsInfo->length[subBlockNumber][HIFILT] = sfbCnt - tC->lpcStartBand[HIFILT];
|
||||
|
||||
/* disable TNS if predictionGain is less than 3dB or sumSqrCoef is too small */
|
||||
if ((tsbi->predictionGain > tC->confTab.threshOn[HIFILT]) || (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT]/2 + 2)))
|
||||
if ((tsbi->predictionGain[HIFILT] > tC->confTab.threshOn[HIFILT]) || (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT]/2 + 2)))
|
||||
{
|
||||
tsbi->tnsActive = TRUE;
|
||||
tsbi->tnsActive[HIFILT] = TRUE;
|
||||
tnsInfo->numOfFilters[subBlockNumber]++;
|
||||
|
||||
/* compute second filter for lower quarter; only allowed for long windows! */
|
||||
@ -857,6 +845,7 @@ INT FDKaacEnc_TnsDetect(
|
||||
|| ( (sumSqrCoef > 9) && (sumSqrCoef < 22 * tC->confTab.tnsLimitOrder[LOFILT]) ) )
|
||||
{
|
||||
/* compare lower to upper filter; if they are very similar, merge them */
|
||||
tsbi->tnsActive[LOFILT] = TRUE;
|
||||
sumSqrCoef = 0;
|
||||
for (i = 0; i < tC->confTab.tnsLimitOrder[LOFILT]; i++) {
|
||||
sumSqrCoef += FDKabs(tnsInfo->coef[subBlockNumber][HIFILT][i] - tnsInfo->coef[subBlockNumber][LOFILT][i]);
|
||||
@ -884,6 +873,8 @@ INT FDKaacEnc_TnsDetect(
|
||||
tnsInfo->numOfFilters[subBlockNumber]++;
|
||||
}
|
||||
} /* filter lower part */
|
||||
tsbi->predictionGain[LOFILT]=predGain;
|
||||
|
||||
} /* second filter allowed */
|
||||
} /* if predictionGain > 1437 ... */
|
||||
} /* maxOrder > 0 && tnsActive */
|
||||
@ -944,7 +935,7 @@ void FDKaacEnc_TnsSync(
|
||||
INT doSync = 1, absDiffSum = 0;
|
||||
|
||||
/* if TNS is active in at least one channel, check if ParCor coefficients of higher filter are similar */
|
||||
if (pSbInfoDestW->tnsActive || pSbInfoSrcW->tnsActive) {
|
||||
if (pSbInfoDestW->tnsActive[HIFILT] || pSbInfoSrcW->tnsActive[HIFILT]) {
|
||||
for (i = 0; i < tC->maxOrder; i++) {
|
||||
absDiff = FDKabs(tnsInfoDest->coef[w][HIFILT][i] - tnsInfoSrc->coef[w][HIFILT][i]);
|
||||
absDiffSum += absDiff;
|
||||
@ -957,12 +948,12 @@ void FDKaacEnc_TnsSync(
|
||||
|
||||
if (doSync) {
|
||||
/* if no significant difference was detected, synchronize coefficient sets */
|
||||
if (pSbInfoSrcW->tnsActive) {
|
||||
if (pSbInfoSrcW->tnsActive[HIFILT]) {
|
||||
/* no dest filter, or more dest than source filters: use one dest filter */
|
||||
if ((!pSbInfoDestW->tnsActive) ||
|
||||
((pSbInfoDestW->tnsActive) && (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w])))
|
||||
if ((!pSbInfoDestW->tnsActive[HIFILT]) ||
|
||||
((pSbInfoDestW->tnsActive[HIFILT]) && (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w])))
|
||||
{
|
||||
pSbInfoDestW->tnsActive = tnsInfoDest->numOfFilters[w] = 1;
|
||||
pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 1;
|
||||
}
|
||||
tnsDataDest->filtersMerged = tnsDataSrc->filtersMerged;
|
||||
tnsInfoDest->order [w][HIFILT] = tnsInfoSrc->order [w][HIFILT];
|
||||
@ -975,7 +966,7 @@ void FDKaacEnc_TnsSync(
|
||||
}
|
||||
}
|
||||
else
|
||||
pSbInfoDestW->tnsActive = tnsInfoDest->numOfFilters[w] = 0;
|
||||
pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1012,8 +1003,8 @@ INT FDKaacEnc_TnsEncode(
|
||||
{
|
||||
INT i, startLine, stopLine;
|
||||
|
||||
if ( ( (blockType == SHORT_WINDOW) && (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber].tnsActive) )
|
||||
|| ( (blockType != SHORT_WINDOW) && (!tnsData->dataRaw.Long.subBlockInfo.tnsActive) ) )
|
||||
if ( ( (blockType == SHORT_WINDOW) && (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber].tnsActive[HIFILT]) )
|
||||
|| ( (blockType != SHORT_WINDOW) && (!tnsData->dataRaw.Long.subBlockInfo.tnsActive[HIFILT]) ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -1129,8 +1120,9 @@ static INT FDKaacEnc_AutoToParcor(
|
||||
FIXP_DBL *RESTRICT workBuffer = parcorWorkBuffer;
|
||||
const FIXP_DBL autoCorr_0 = input[0];
|
||||
|
||||
FDKmemclear(reflCoeff,numOfCoeff*sizeof(FIXP_DBL));
|
||||
|
||||
if((FIXP_DBL)input[0] == FL2FXCONST_DBL(0.0)) {
|
||||
FDKmemclear(reflCoeff,numOfCoeff*sizeof(FIXP_DBL));
|
||||
return(predictionGain);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -117,21 +117,25 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
#define MAX_NUM_OF_FILTERS 2
|
||||
|
||||
#define HIFILT 0 /* index of higher filter */
|
||||
#define LOFILT 1 /* index of lower filter */
|
||||
|
||||
typedef struct{ /*stuff that is tabulated dependent on bitrate etc. */
|
||||
INT filterEnabled[MAX_NUM_OF_FILTERS];
|
||||
INT threshOn[MAX_NUM_OF_FILTERS]; /* min. prediction gain for using tns TABUL*/
|
||||
INT tnsLimitOrder[MAX_NUM_OF_FILTERS]; /* Limit for TNS order TABUL*/
|
||||
INT tnsFilterDirection[MAX_NUM_OF_FILTERS]; /* Filtering direction, 0=up, 1=down TABUL */
|
||||
INT acfSplit[MAX_NUM_OF_FILTERS];
|
||||
INT seperateFiltersAllowed;
|
||||
|
||||
}TNS_CONFIG_TABULATED;
|
||||
|
||||
typedef struct{ /* stuff that is tabulated dependent on bitrate etc. */
|
||||
INT filterEnabled[MAX_NUM_OF_FILTERS];
|
||||
INT threshOn[MAX_NUM_OF_FILTERS]; /* min. prediction gain for using tns TABUL*/
|
||||
INT filterStartFreq[MAX_NUM_OF_FILTERS]; /* lowest freq for lpc TABUL*/
|
||||
INT tnsLimitOrder[MAX_NUM_OF_FILTERS]; /* Limit for TNS order TABUL*/
|
||||
INT tnsFilterDirection[MAX_NUM_OF_FILTERS]; /* Filtering direction, 0=up, 1=down TABUL */
|
||||
INT acfSplit[MAX_NUM_OF_FILTERS];
|
||||
FIXP_DBL tnsTimeResolution[MAX_NUM_OF_FILTERS]; /* TNS max. time resolution TABUL. Should be fract but MSVC won't compile then */
|
||||
INT seperateFiltersAllowed;
|
||||
} TNS_PARAMETER_TABULATED;
|
||||
|
||||
|
||||
typedef struct { /*assigned at InitTime*/
|
||||
TNS_CONFIG_TABULATED confTab;
|
||||
TNS_PARAMETER_TABULATED confTab;
|
||||
INT isLowDelay;
|
||||
INT tnsActive;
|
||||
INT maxOrder; /* max. order of tns filter */
|
||||
INT coefRes;
|
||||
@ -148,8 +152,8 @@ typedef struct { /*assigned at InitTime*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
INT tnsActive;
|
||||
INT predictionGain;
|
||||
INT tnsActive[MAX_NUM_OF_FILTERS];
|
||||
INT predictionGain[MAX_NUM_OF_FILTERS];
|
||||
} TNS_SUBBLOCK_INFO;
|
||||
|
||||
typedef struct{ /*changed at runTime*/
|
||||
|
@ -153,10 +153,10 @@ static const BIT_PE_SFAC S_Bits2PeTab16000[] = {
|
||||
{ 24000, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413},
|
||||
{ 32000, 0x247AE148, 0x11B1D92B, 0x23851EB8, 0x01F75105, 0x247AE148, 0x110A137F, 0x23851EB8, 0x01F75105},
|
||||
{ 48000, 0x2D1EB852, 0x6833C600, 0x247AE148, 0x014F8B59, 0x2CCCCCCD, 0x68DB8BAC, 0x247AE148, 0x01F75105},
|
||||
{ 64000, 0x60000000, 0x00000000, 0x251EB852, 0x154C985F, 0x60000000, 0x00000000, 0x2570A3D7, 0x154C985F},
|
||||
{ 96000, 0x60000000, 0x00000000, 0x39EB851F, 0x088509C0, 0x60000000, 0x00000000, 0x3A3D70A4, 0x088509C0},
|
||||
{128000, 0x60000000, 0x00000000, 0x423D70A4, 0x18A43BB4, 0x60000000, 0x00000000, 0x428F5C29, 0x181E03F7},
|
||||
{148000, 0x60000000, 0x00000000, 0x5147AE14, 0x00000000, 0x60000000, 0x00000000, 0x5147AE14, 0x00000000}
|
||||
{ 64000, 0x25c28f40, 0x00000000, 0x251EB852, 0x01480000, 0x25c28f40, 0x00000000, 0x2570A3D7, 0x01480000},
|
||||
{ 96000, 0x25c28f40, 0x00000000, 0x26000000, 0x01000000, 0x25c28f40, 0x00000000, 0x26000000, 0x01000000},
|
||||
{128000, 0x25c28f40, 0x00000000, 0x270a3d80, 0x01000000, 0x25c28f40, 0x00000000, 0x270a3d80, 0x01000000},
|
||||
{148000, 0x25c28f40, 0x00000000, 0x28000000, 0x00000000, 0x25c28f40, 0x00000000, 0x28000000, 0x00000000}
|
||||
};
|
||||
|
||||
static const BIT_PE_SFAC S_Bits2PeTab22050[] = {
|
||||
@ -166,8 +166,8 @@ static const BIT_PE_SFAC S_Bits2PeTab22050[] = {
|
||||
{ 48000, 0x23d70a3d, 0x014f8b59, 0x2199999a, 0x03eea20a, 0x23d70a3d, 0x14f8b59, 0x2199999a, 0x03eea20a},
|
||||
{ 64000, 0x247ae148, 0x08d8ec96, 0x23851eb8, 0x00fba882, 0x247ae148, 0x88509c0, 0x23851eb8, 0x00fba882},
|
||||
{ 96000, 0x2d1eb852, 0x3419e300, 0x247ae148, 0x00a7c5ac, 0x2ccccccd, 0x346dc5d6, 0x247ae148, 0x00fba882},
|
||||
{128000, 0x60000000, 0x00000000, 0x251eb852, 0x029f16b1, 0x60000000, 0x00000000, 0x2570a3d7, 0x009f16b1},
|
||||
{148000, 0x60000000, 0x00000000, 0x26b851ec, 0x00000000, 0x60000000, 0x00000000, 0x270a3d71, 0x00000000}
|
||||
{128000, 0x25c28f40, 0x00000000, 0x251eb852, 0x029f16b1, 0x60000000, 0x25c28f40, 0x2570a3d7, 0x009f16b1},
|
||||
{148000, 0x25c28f40, 0x00000000, 0x26b851ec, 0x00000000, 0x60000000, 0x25c28f40, 0x270a3d71, 0x00000000}
|
||||
};
|
||||
|
||||
static const BIT_PE_SFAC S_Bits2PeTab24000[] = {
|
||||
@ -178,21 +178,21 @@ static const BIT_PE_SFAC S_Bits2PeTab24000[] = {
|
||||
{ 64000, 0x24cccccd, 0x05e5f30e, 0x22e147ae, 0x01a36e2f, 0x24cccccd, 0x05e5f30e, 0x23333333, 0x014f8b59},
|
||||
{ 96000, 0x2a8f5c29, 0x24b33db0, 0x247ae148, 0x00fba882, 0x2a8f5c29, 0x26fe718b, 0x247ae148, 0x00fba882},
|
||||
{128000, 0x4e666666, 0x1cd5f99c, 0x2570a3d7, 0x010c6f7a, 0x50a3d70a, 0x192a7371, 0x2570a3d7, 0x010c6f7a},
|
||||
{148000, 0x60000000, 0x00000000, 0x26147ae1, 0x00000000, 0x60000000, 0x00000000, 0x26147ae1, 0x00000000}
|
||||
{148000, 0x25c28f40, 0x00000000, 0x26147ae1, 0x00000000, 0x25c28f40, 0x00000000, 0x26147ae1, 0x00000000}
|
||||
};
|
||||
|
||||
static const BIT_PE_SFAC S_Bits2PeTab32000[] = {
|
||||
{ 16000, 0x1199999a, 0x20c49ba6, 0x00000000, 0x4577d955, 0x00000000, 0x60fe4799, 0x00000000, 0x00000000},
|
||||
{ 24000, 0x1999999a, 0x0fba8827, 0x10f5c28f, 0x1b866e44, 0x17ae147b, 0x0fba8827, 0x00000000, 0x4d551d69},
|
||||
{ 16000, 0x247ae140, 0xFFFFAC1E, 0x270a3d80, 0xFFFE9B7C, 0x14ccccc0, 0x000110A1, 0x15c28f60, 0xFFFEEF5F},
|
||||
{ 24000, 0x23333340, 0x0fba8827, 0x21999980, 0x1b866e44, 0x18f5c280, 0x0fba8827, 0x119999a0, 0x4d551d69},
|
||||
{ 32000, 0x1d70a3d7, 0x07357e67, 0x17ae147b, 0x09d49518, 0x1b851eb8, 0x0a7c5ac4, 0x12e147ae, 0x110a137f},
|
||||
{ 48000, 0x20f5c28f, 0x049667b6, 0x1c7ae148, 0x053e2d62, 0x20a3d70a, 0x053e2d62, 0x1b333333, 0x05e5f30e},
|
||||
{ 64000, 0x23333333, 0x029f16b1, 0x1f0a3d71, 0x02f2f987, 0x23333333, 0x029f16b1, 0x1e147ae1, 0x03eea20a},
|
||||
{ 96000, 0x25c28f5c, 0x2c3c9eed, 0x21eb851f, 0x01f75105, 0x25c28f5c, 0x0a7c5ac4, 0x21eb851f, 0x01a36e2f},
|
||||
{128000, 0x50f5c28f, 0x18a43bb4, 0x23d70a3d, 0x010c6f7a, 0x30000000, 0x168b5cc0, 0x23851eb8, 0x0192a737},
|
||||
{148000, 0x60000000, 0x00000000, 0x247ae148, 0x00dfb23b, 0x3dc28f5c, 0x300f4aaf, 0x247ae148, 0x01bf6476},
|
||||
{160000, 0x60000000, 0xb15b5740, 0x24cccccd, 0x053e2d62, 0x4f5c28f6, 0xbefd0072, 0x251eb852, 0x04fb1184},
|
||||
{200000, 0x00000000, 0x00000000, 0x2b333333, 0x0836be91, 0x00000000, 0x00000000, 0x2b333333, 0x0890390f},
|
||||
{320000, 0x00000000, 0x00000000, 0x4947ae14, 0x00000000, 0x00000000, 0x00000000, 0x4a8f5c29, 0x00000000}
|
||||
{148000, 0x25c28f40, 0x00000000, 0x247ae148, 0x00dfb23b, 0x3dc28f5c, 0x300f4aaf, 0x247ae148, 0x01bf6476},
|
||||
{160000, 0x25c28f40, 0xb15b5740, 0x24cccccd, 0x053e2d62, 0x4f5c28f6, 0xbefd0072, 0x251eb852, 0x04fb1184},
|
||||
{200000, 0x25c28f40, 0x00000000, 0x2b333333, 0x0836be91, 0x25c28f40, 0x00000000, 0x2b333333, 0x0890390f},
|
||||
{320000, 0x25c28f40, 0x00000000, 0x4947ae14, 0x00000000, 0x25c28f40, 0x00000000, 0x4a8f5c29, 0x00000000}
|
||||
};
|
||||
|
||||
static const BIT_PE_SFAC S_Bits2PeTab44100[] = {
|
||||
@ -205,8 +205,8 @@ static const BIT_PE_SFAC S_Bits2PeTab44100[] = {
|
||||
{128000, 0x2ae147ae, 0x1b435265, 0x223d70a4, 0x0192a737, 0x2a3d70a4, 0x1040bfe4, 0x21eb851f, 0x0192a737},
|
||||
{148000, 0x3b851eb8, 0x2832069c, 0x23333333, 0x00dfb23b, 0x3428f5c3, 0x2054c288, 0x22e147ae, 0x00dfb23b},
|
||||
{160000, 0x4a3d70a4, 0xc32ebe5a, 0x23851eb8, 0x01d5c316, 0x40000000, 0xcb923a2b, 0x23333333, 0x01d5c316},
|
||||
{200000, 0x00000000, 0x00000000, 0x25c28f5c, 0x0713f078, 0x00000000, 0x00000000, 0x2570a3d7, 0x072a4f17},
|
||||
{320000, 0x00000000, 0x00000000, 0x3fae147b, 0x00000000, 0x00000000, 0x00000000, 0x3fae147b, 0x00000000}
|
||||
{200000, 0x25c28f40, 0x00000000, 0x25c28f5c, 0x0713f078, 0x25c28f40, 0x00000000, 0x2570a3d7, 0x072a4f17},
|
||||
{320000, 0x25c28f40, 0x00000000, 0x3fae147b, 0x00000000, 0x25c28f40, 0x00000000, 0x3fae147b, 0x00000000}
|
||||
};
|
||||
|
||||
static const BIT_PE_SFAC S_Bits2PeTab48000[] = {
|
||||
@ -219,8 +219,8 @@ static const BIT_PE_SFAC S_Bits2PeTab48000[] = {
|
||||
{128000, 0x28f5c28f, 0x14727dcc, 0x2147ae14, 0x0218def4, 0x2851eb85, 0x0e27e0f0, 0x20f5c28f, 0x0218def4},
|
||||
{148000, 0x3570a3d7, 0x1cd5f99c, 0x228f5c29, 0x01bf6476, 0x30f5c28f, 0x18777e75, 0x223d70a4, 0x01bf6476},
|
||||
{160000, 0x40000000, 0xcb923a2b, 0x23333333, 0x0192a737, 0x39eb851f, 0xd08d4bae, 0x22e147ae, 0x0192a737},
|
||||
{200000, 0x00000000, 0x00000000, 0x251eb852, 0x06775a1b, 0x00000000, 0x00000000, 0x24cccccd, 0x06a4175a},
|
||||
{320000, 0x00000000, 0x00000000, 0x3ccccccd, 0x00000000, 0x00000000, 0x00000000, 0x3d1eb852, 0x00000000}
|
||||
{200000, 0x25c28f40, 0x00000000, 0x251eb852, 0x06775a1b, 0x25c28f40, 0x00000000, 0x24cccccd, 0x06a4175a},
|
||||
{320000, 0x25c28f40, 0x00000000, 0x3ccccccd, 0x00000000, 0x25c28f40, 0x00000000, 0x3d1eb852, 0x00000000}
|
||||
};
|
||||
|
||||
static const BITS2PE_CFG_TAB bits2PeConfigTab[] = {
|
||||
@ -258,6 +258,7 @@ static void FDKaacEnc_InitBits2PeFactor(
|
||||
const INT nChannels,
|
||||
const INT sampleRate,
|
||||
const INT advancedBitsToPe,
|
||||
const INT dZoneQuantEnable,
|
||||
const INT invQuant
|
||||
)
|
||||
{
|
||||
@ -329,7 +330,32 @@ static void FDKaacEnc_InitBits2PeFactor(
|
||||
} /* advancedBitsToPe */
|
||||
|
||||
|
||||
/* return bits2pe factor */
|
||||
if (dZoneQuantEnable)
|
||||
{
|
||||
if(bit2PE_m >= (FL2FXCONST_DBL(0.6f))>>bit2PE_e)
|
||||
{
|
||||
/* Additional headroom for addition */
|
||||
bit2PE_m >>= 1;
|
||||
bit2PE_e += 1;
|
||||
}
|
||||
|
||||
/* the quantTendencyCompensator compensates a lower bit consumption due to increasing the tendency to quantize low spectral values to the lower quantizer border for bitrates below a certain bitrate threshold --> see also function calcSfbDistLD in quantize.c */
|
||||
if ((bitRate/nChannels > 32000) && (bitRate/nChannels <= 40000)) {
|
||||
bit2PE_m += (FL2FXCONST_DBL(0.4f))>>bit2PE_e;
|
||||
}
|
||||
else if (bitRate/nChannels > 20000) {
|
||||
bit2PE_m += (FL2FXCONST_DBL(0.3f))>>bit2PE_e;
|
||||
}
|
||||
else if (bitRate/nChannels >= 16000) {
|
||||
bit2PE_m += (FL2FXCONST_DBL(0.3f))>>bit2PE_e;
|
||||
}
|
||||
else {
|
||||
bit2PE_m += (FL2FXCONST_DBL(0.0f))>>bit2PE_e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***** 3.) Return bits2pe factor *****/
|
||||
*bits2PeFactor_m = bit2PE_m;
|
||||
*bits2PeFactor_e = bit2PE_e;
|
||||
}
|
||||
@ -1649,6 +1675,7 @@ static void FDKaacEnc_adaptThresholdsToPe(CHANNEL_MAPPING* cm,
|
||||
QC_OUT_ELEMENT* qcElement[(8)],
|
||||
PSY_OUT_ELEMENT* psyOutElement[(8)],
|
||||
const INT desiredPe,
|
||||
const INT maxIter2ndGuess,
|
||||
const INT processElements,
|
||||
const INT elementOffset)
|
||||
{
|
||||
@ -1733,7 +1760,7 @@ static void FDKaacEnc_adaptThresholdsToPe(CHANNEL_MAPPING* cm,
|
||||
/* Part III: Iterate until bit constraints are met */
|
||||
/* -------------------------------------------------- */
|
||||
iter = 0;
|
||||
while ((fixp_abs(redPeGlobal - desiredPe) > fMultI(FL2FXCONST_DBL(0.05f),desiredPe)) && (iter < 1)) {
|
||||
while ((fixp_abs(redPeGlobal - desiredPe) > fMultI(FL2FXCONST_DBL(0.05f),desiredPe)) && (iter < maxIter2ndGuess)) {
|
||||
|
||||
INT desiredPeNoAHGlobal;
|
||||
INT redPeNoAHGlobal = 0;
|
||||
@ -2225,7 +2252,8 @@ void FDKaacEnc_AdjThrInit(
|
||||
INT nChannelsEff,
|
||||
INT sampleRate,
|
||||
INT advancedBitsToPe,
|
||||
FIXP_DBL vbrQualFactor
|
||||
FIXP_DBL vbrQualFactor,
|
||||
const INT dZoneQuantEnable
|
||||
)
|
||||
{
|
||||
INT i;
|
||||
@ -2233,6 +2261,10 @@ void FDKaacEnc_AdjThrInit(
|
||||
FIXP_DBL POINT8 = FL2FXCONST_DBL(0.8f);
|
||||
FIXP_DBL POINT6 = FL2FXCONST_DBL(0.6f);
|
||||
|
||||
/* Max number of iterations in second guess is 3 for lowdelay aot and for configurations with
|
||||
multiple audio elements in general, otherwise iteration value is always 1. */
|
||||
hAdjThr->maxIter2ndGuess = (advancedBitsToPe!=0 || nElements>1) ? 3 : 1;
|
||||
|
||||
/* common for all elements: */
|
||||
/* parameters for bitres control */
|
||||
hAdjThr->bresParamLong.clipSaveLow = (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */
|
||||
@ -2313,10 +2345,11 @@ void FDKaacEnc_AdjThrInit(
|
||||
FDKaacEnc_InitBits2PeFactor(
|
||||
&atsElem->bits2PeFactor_m,
|
||||
&atsElem->bits2PeFactor_e,
|
||||
chBitrate, /* bitrate/channel*/
|
||||
chBitrate*nChannelsEff, /* overall bitrate */
|
||||
nChannelsEff, /* number of channels */
|
||||
sampleRate,
|
||||
advancedBitsToPe,
|
||||
dZoneQuantEnable,
|
||||
invQuant
|
||||
);
|
||||
|
||||
@ -2545,6 +2578,7 @@ void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)],
|
||||
QC_OUT* qcOut,
|
||||
PSY_OUT_ELEMENT* psyOutElement[(8)],
|
||||
INT CBRbitrateMode,
|
||||
INT maxIter2ndGuess,
|
||||
CHANNEL_MAPPING* cm)
|
||||
{
|
||||
int i;
|
||||
@ -2570,6 +2604,7 @@ void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)],
|
||||
qcElement,
|
||||
psyOutElement,
|
||||
qcElement[i]->grantedPeCorr,
|
||||
maxIter2ndGuess,
|
||||
1, /* Process only 1 element */
|
||||
i); /* Process exactly THIS element */
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -118,7 +118,8 @@ void FDKaacEnc_AdjThrInit(ADJ_THR_STATE *hAdjThr,
|
||||
INT nChannelsEff,
|
||||
INT sampleRate,
|
||||
INT advancedBitsToPe,
|
||||
FIXP_DBL vbrQualFactor);
|
||||
FIXP_DBL vbrQualFactor,
|
||||
const INT dZoneQuantEnable);
|
||||
|
||||
|
||||
void FDKaacEnc_DistributeBits(ADJ_THR_STATE *adjThrState,
|
||||
@ -140,6 +141,7 @@ void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)],
|
||||
QC_OUT* qcOut,
|
||||
PSY_OUT_ELEMENT* psyOutElement[(8)],
|
||||
INT CBRbitrateMode,
|
||||
INT maxIter2ndGuess,
|
||||
CHANNEL_MAPPING* cm);
|
||||
|
||||
void FDKaacEnc_AdjThrClose(ADJ_THR_STATE** hAdjThr);
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -145,6 +145,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
BRES_PARAM bresParamLong, bresParamShort;
|
||||
ATS_ELEMENT* adjThrStateElem[(8)];
|
||||
INT maxIter2ndGuess;
|
||||
} ADJ_THR_STATE;
|
||||
|
||||
#endif
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -127,7 +127,7 @@ static const BANDWIDTH_TAB bandWidthTable_LD_24000[] = {
|
||||
{ 8000, 2000, 2000},
|
||||
{12000, 2000, 2300},
|
||||
{16000, 2200, 2500},
|
||||
{24000, 5650, 6400},
|
||||
{24000, 5650, 7200},
|
||||
{32000, 11600, 12000},
|
||||
{40000, 12000, 16000},
|
||||
{48000, 16000, 16000},
|
||||
@ -138,10 +138,10 @@ static const BANDWIDTH_TAB bandWidthTable_LD_24000[] = {
|
||||
static const BANDWIDTH_TAB bandWidthTable_LD_32000[] = {
|
||||
{ 8000, 2000, 2000},
|
||||
{12000, 2000, 2000},
|
||||
{24000, 4250, 5200},
|
||||
{24000, 4250, 7200},
|
||||
{32000, 8400, 9000},
|
||||
{40000, 9400, 11300},
|
||||
{48000, 11900, 13700},
|
||||
{48000, 11900, 14700},
|
||||
{64000, 14800, 16000},
|
||||
{76000, 16000, 16000},
|
||||
{360001, 16000, 16000}
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -107,6 +107,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
ULONG brFrom;
|
||||
ULONG brTo;
|
||||
UCHAR S16000;
|
||||
UCHAR S22050;
|
||||
UCHAR S24000;
|
||||
UCHAR S32000;
|
||||
@ -115,25 +116,26 @@ typedef struct {
|
||||
} AUTO_PNS_TAB;
|
||||
|
||||
static const AUTO_PNS_TAB levelTable_mono[]= {
|
||||
{0, 11999, 1, 1, 1, 1, 1,},
|
||||
{12000, 19999, 1, 1, 1, 1, 1,},
|
||||
{20000, 28999, 2, 1, 1, 1, 1,},
|
||||
{29000, 40999, 4, 4, 4, 2, 2,},
|
||||
{41000, 55999, 9, 9, 7, 7, 7,},
|
||||
{56000, 79999, 0, 0, 0, 9, 9,},
|
||||
{80000, 99999, 0, 0, 0, 0, 0,},
|
||||
{100000,999999, 0, 0, 0, 0, 0,},
|
||||
{0, 11999, 0, 1, 1, 1, 1, 1,},
|
||||
{12000, 19999, 0, 1, 1, 1, 1, 1,},
|
||||
{20000, 28999, 0, 2, 1, 1, 1, 1,},
|
||||
{29000, 40999, 0, 4, 4, 4, 2, 2,},
|
||||
{41000, 55999, 0, 9, 9, 7, 7, 7,},
|
||||
{56000, 61999, 0, 0, 0, 0, 9, 9,},
|
||||
{62000, 75999, 0, 0, 0, 0, 0, 0,},
|
||||
{76000, 92999, 0, 0, 0, 0, 0, 0,},
|
||||
{93000, 999999, 0, 0, 0, 0, 0, 0,},
|
||||
};
|
||||
|
||||
static const AUTO_PNS_TAB levelTable_stereo[]= {
|
||||
{0, 11999, 1, 1, 1, 1, 1,},
|
||||
{12000, 19999, 3, 1, 1, 1, 1,},
|
||||
{20000, 28999, 3, 3, 3, 2, 2,},
|
||||
{29000, 40999, 7, 6, 6, 5, 5,},
|
||||
{41000, 55999, 9, 9, 7, 7, 7,},
|
||||
{56000, 79999, 0, 0, 0, 0, 0,},
|
||||
{80000, 99999, 0, 0, 0, 0, 0,},
|
||||
{100000,999999, 0, 0, 0, 0, 0,},
|
||||
{0, 11999, 0, 1, 1, 1, 1, 1,},
|
||||
{12000, 19999, 0, 3, 1, 1, 1, 1,},
|
||||
{20000, 28999, 0, 3, 3, 3, 2, 2,},
|
||||
{29000, 40999, 0, 7, 6, 6, 5, 5,},
|
||||
{41000, 55999, 0, 9, 9, 7, 7, 7,},
|
||||
{56000, 79999, 0, 0, 0, 0, 0, 0,},
|
||||
{80000, 99999, 0, 0, 0, 0, 0, 0,},
|
||||
{100000,999999, 0, 0, 0, 0, 0, 0,},
|
||||
};
|
||||
|
||||
|
||||
@ -160,11 +162,11 @@ static const PNS_INFO_TAB pnsInfoTab[] = {
|
||||
};
|
||||
|
||||
static const AUTO_PNS_TAB levelTable_lowComplexity[]= {
|
||||
{0, 27999, 0, 0, 0, 0, 0,},
|
||||
{28000, 31999, 2, 2, 2, 2, 2,},
|
||||
{32000, 47999, 3, 3, 3, 3, 3,},
|
||||
{48000, 48000, 4, 4, 4, 4, 4,},
|
||||
{48001, 999999, 0, 0, 0, 0, 0,},
|
||||
{0, 27999, 0, 0, 0, 0, 0, 0,},
|
||||
{28000, 31999, 0, 2, 2, 2, 2, 2,},
|
||||
{32000, 47999, 0, 3, 3, 3, 3, 3,},
|
||||
{48000, 48000, 0, 4, 4, 4, 4, 4,},
|
||||
{48001, 999999, 0, 0, 0, 0, 0, 0,},
|
||||
};
|
||||
|
||||
/* conversion of old LC tuning tables to new (LD enc) structure (only entries which are actually used were converted) */
|
||||
@ -211,6 +213,7 @@ int FDKaacEnc_lookUpPnsUse (int bitRate, int sampleRate, int numChan, const int
|
||||
}
|
||||
|
||||
switch (sampleRate) {
|
||||
case 16000: hUsePns = levelTable[i].S16000; break;
|
||||
case 22050: hUsePns = levelTable[i].S22050; break;
|
||||
case 24000: hUsePns = levelTable[i].S24000; break;
|
||||
case 32000: hUsePns = levelTable[i].S32000; break;
|
||||
|
@ -342,6 +342,7 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(PSY_INTERNAL *hPsy,
|
||||
tnsChannels,
|
||||
LONG_WINDOW,
|
||||
hPsy->granuleLength,
|
||||
isLowDelay(audioObjectType),
|
||||
(syntaxFlags&AC_SBR_PRESENT)?1:0,
|
||||
&(hPsy->psyConf[0].tnsConf),
|
||||
&hPsy->psyConf[0],
|
||||
@ -362,6 +363,7 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(PSY_INTERNAL *hPsy,
|
||||
tnsChannels,
|
||||
SHORT_WINDOW,
|
||||
hPsy->granuleLength,
|
||||
isLowDelay(audioObjectType),
|
||||
(syntaxFlags&AC_SBR_PRESENT)?1:0,
|
||||
&hPsy->psyConf[1].tnsConf,
|
||||
&hPsy->psyConf[1],
|
||||
@ -763,7 +765,8 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels,
|
||||
|
||||
/* Advance psychoacoustics: Tonality and TNS */
|
||||
if (psyStatic[0]->isLFE) {
|
||||
tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive = 0;
|
||||
tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] = 0;
|
||||
tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -819,11 +822,15 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels,
|
||||
for(w = 0; w < nWindows[0]; w++)
|
||||
{
|
||||
if (isShortWindow[0])
|
||||
tnsActive[w] = tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive ||
|
||||
((channels == 2) ? tnsData[1]->dataRaw.Short.subBlockInfo[w].tnsActive : 0);
|
||||
tnsActive[w] = tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] ||
|
||||
tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[LOFILT] ||
|
||||
tnsData[channels-1]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] ||
|
||||
tnsData[channels-1]->dataRaw.Short.subBlockInfo[w].tnsActive[LOFILT];
|
||||
else
|
||||
tnsActive[w] = tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive ||
|
||||
((channels == 2) ? tnsData[1]->dataRaw.Long.subBlockInfo.tnsActive : 0);
|
||||
tnsActive[w] = tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] ||
|
||||
tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] ||
|
||||
tnsData[channels-1]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] ||
|
||||
tnsData[channels-1]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT];
|
||||
}
|
||||
|
||||
for(ch = 0; ch < channels; ch++) {
|
||||
@ -1150,8 +1157,8 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels,
|
||||
psyData[ch]->sfbMaxScaleSpec.Long,
|
||||
sfbTonality[ch],
|
||||
psyOutChannel[ch]->tnsInfo.order[0][0],
|
||||
tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain,
|
||||
tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive,
|
||||
tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain[HIFILT],
|
||||
tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT],
|
||||
psyOutChannel[ch]->sfbEnergyLdData,
|
||||
psyOutChannel[ch]->noiseNrg );
|
||||
} /* !isLFE */
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -269,6 +269,8 @@ typedef struct
|
||||
BITCNTR_STATE *hBitCounter;
|
||||
ADJ_THR_STATE *hAdjThr;
|
||||
|
||||
INT dZoneQuantEnable; /* enable dead zone quantizer */
|
||||
|
||||
} QC_STATE;
|
||||
|
||||
#endif /* _QC_DATA_H */
|
||||
|
@ -380,7 +380,7 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC,
|
||||
if ( isConstantBitrateMode(hQC->bitrateMode) ) {
|
||||
INT bitresPerChannel = (hQC->bitResTotMax / init->channelMapping->nChannelsEff);
|
||||
/* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir */
|
||||
hQC->bitDistributionMode = (bitresPerChannel>100) ? 0 : (bitresPerChannel>0) ? 1 : 2;
|
||||
hQC->bitDistributionMode = (bitresPerChannel>BITRES_MIN_LD) ? 0 : (bitresPerChannel>0) ? 1 : 2;
|
||||
}
|
||||
else {
|
||||
hQC->bitDistributionMode = 0; /* full bitreservoir */
|
||||
@ -405,6 +405,16 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC,
|
||||
}
|
||||
}
|
||||
|
||||
if (init->channelMapping->nChannelsEff == 1 &&
|
||||
(init->bitrate / init->channelMapping->nChannelsEff) < 32000 &&
|
||||
init->advancedBitsToPe != 0
|
||||
)
|
||||
{
|
||||
hQC->dZoneQuantEnable = 1;
|
||||
} else {
|
||||
hQC->dZoneQuantEnable = 0;
|
||||
}
|
||||
|
||||
FDKaacEnc_AdjThrInit(
|
||||
hQC->hAdjThr,
|
||||
init->meanPe,
|
||||
@ -414,7 +424,8 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC,
|
||||
init->channelMapping->nChannelsEff,
|
||||
init->sampleRate, /* output sample rate */
|
||||
init->advancedBitsToPe, /* if set, calc bits2PE factor depending on samplerate */
|
||||
hQC->vbrQualFactor
|
||||
hQC->vbrQualFactor,
|
||||
hQC->dZoneQuantEnable
|
||||
);
|
||||
|
||||
return AAC_ENC_OK;
|
||||
@ -877,6 +888,7 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC,
|
||||
qcOut[c],
|
||||
psyOut[c]->psyOutElement,
|
||||
isConstantBitrateMode(hQC->bitrateMode),
|
||||
hQC->hAdjThr->maxIter2ndGuess,
|
||||
cm);
|
||||
|
||||
} /* -end- sub frame counter */
|
||||
@ -904,6 +916,7 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC,
|
||||
FDKaacEnc_EstimateScaleFactors(psyOut[c]->psyOutElement[i]->psyOutChannel,
|
||||
qcElement[c][i]->qcOutChannel,
|
||||
hQC->invQuant,
|
||||
hQC->dZoneQuantEnable,
|
||||
cm->elInfo[i].nChannelsInEl);
|
||||
|
||||
|
||||
@ -998,7 +1011,8 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC,
|
||||
qcOutCh->mdctSpectrum,
|
||||
qcOutCh->globalGain,
|
||||
qcOutCh->scf,
|
||||
qcOutCh->quantSpec) ;
|
||||
qcOutCh->quantSpec,
|
||||
hQC->dZoneQuantEnable);
|
||||
|
||||
/*-------------------------------------------- */
|
||||
if (FDKaacEnc_calcMaxValueInSfb(psyOutCh->sfbCnt,
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -104,13 +104,19 @@ amm-info@iis.fraunhofer.de
|
||||
static void FDKaacEnc_quantizeLines(INT gain,
|
||||
INT noOfLines,
|
||||
FIXP_DBL *mdctSpectrum,
|
||||
SHORT *quaSpectrum)
|
||||
SHORT *quaSpectrum,
|
||||
INT dZoneQuantEnable)
|
||||
{
|
||||
int line;
|
||||
FIXP_DBL k = FL2FXCONST_DBL(-0.0946f + 0.5f)>>16;
|
||||
FIXP_DBL k = FL2FXCONST_DBL(0.0f);
|
||||
FIXP_QTD quantizer = FDKaacEnc_quantTableQ[(-gain)&3];
|
||||
INT quantizershift = ((-gain)>>2)+1;
|
||||
const INT kShift=16;
|
||||
|
||||
if (dZoneQuantEnable)
|
||||
k = FL2FXCONST_DBL(0.23f)>>kShift;
|
||||
else
|
||||
k = FL2FXCONST_DBL(-0.0946f + 0.5f)>>kShift;
|
||||
|
||||
for (line = 0; line < noOfLines; line++)
|
||||
{
|
||||
@ -263,7 +269,8 @@ void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
|
||||
FIXP_DBL *mdctSpectrum,
|
||||
INT globalGain,
|
||||
INT *scalefactors,
|
||||
SHORT *quantizedSpectrum)
|
||||
SHORT *quantizedSpectrum,
|
||||
INT dZoneQuantEnable)
|
||||
{
|
||||
INT sfbOffs,sfb;
|
||||
|
||||
@ -280,7 +287,8 @@ void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
|
||||
FDKaacEnc_quantizeLines(globalGain - scalefactor, /* QSS */
|
||||
sfbOffset[sfbOffs+sfb+1] - sfbOffset[sfbOffs+sfb],
|
||||
mdctSpectrum + sfbOffset[sfbOffs+sfb],
|
||||
quantizedSpectrum + sfbOffset[sfbOffs+sfb]);
|
||||
quantizedSpectrum + sfbOffset[sfbOffs+sfb],
|
||||
dZoneQuantEnable);
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,7 +304,8 @@ void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
|
||||
FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum,
|
||||
SHORT *quantSpectrum,
|
||||
INT noOfLines,
|
||||
INT gain
|
||||
INT gain,
|
||||
INT dZoneQuantEnable
|
||||
)
|
||||
{
|
||||
INT i,scale;
|
||||
@ -311,7 +320,8 @@ FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum,
|
||||
FDKaacEnc_quantizeLines(gain,
|
||||
1,
|
||||
&mdctSpectrum[i],
|
||||
&quantSpectrum[i]);
|
||||
&quantSpectrum[i],
|
||||
dZoneQuantEnable);
|
||||
|
||||
if (fAbs(quantSpectrum[i])>MAX_QUANT) {
|
||||
return FL2FXCONST_DBL(0.0f);
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -102,12 +102,14 @@ void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
|
||||
INT sfbPerGroup,
|
||||
INT *sfbOffset, FIXP_DBL *mdctSpectrum,
|
||||
INT globalGain, INT *scalefactors,
|
||||
SHORT *quantizedSpectrum);
|
||||
SHORT *quantizedSpectrum,
|
||||
INT dZoneQuantEnable);
|
||||
|
||||
FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum,
|
||||
SHORT *quantSpectrum,
|
||||
INT noOfLines,
|
||||
INT gain);
|
||||
INT gain,
|
||||
INT dZoneQuantEnable);
|
||||
|
||||
void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum,
|
||||
SHORT *quantSpectrum,
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -363,7 +363,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
|
||||
INT scf,
|
||||
INT minScf,
|
||||
FIXP_DBL *distLdData,
|
||||
INT *minScfCalculated
|
||||
INT *minScfCalculated,
|
||||
INT dZoneQuantEnable
|
||||
)
|
||||
{
|
||||
FIXP_DBL sfbDistLdData;
|
||||
@ -375,7 +376,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
|
||||
sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
|
||||
quantSpec,
|
||||
sfbWidth,
|
||||
scf);
|
||||
scf,
|
||||
dZoneQuantEnable);
|
||||
*minScfCalculated = scf;
|
||||
/* nmr > 1.25 -> try to improve nmr */
|
||||
if (sfbDistLdData > (threshLdData-distFactorLdData)) {
|
||||
@ -390,7 +392,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
|
||||
sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
|
||||
quantSpecTmp,
|
||||
sfbWidth,
|
||||
scf);
|
||||
scf,
|
||||
dZoneQuantEnable);
|
||||
|
||||
if (sfbDistLdData < sfbDistBestLdData) {
|
||||
scfBest = scf;
|
||||
@ -408,7 +411,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
|
||||
sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
|
||||
quantSpecTmp,
|
||||
sfbWidth,
|
||||
scf);
|
||||
scf,
|
||||
dZoneQuantEnable);
|
||||
|
||||
if (sfbDistLdData < sfbDistBestLdData) {
|
||||
scfBest = scf;
|
||||
@ -429,7 +433,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
|
||||
sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
|
||||
quantSpecTmp,
|
||||
sfbWidth,
|
||||
scf);
|
||||
scf,
|
||||
dZoneQuantEnable);
|
||||
|
||||
if (sfbDistLdData < sfbDistAllowedLdData) {
|
||||
*minScfCalculated = scfBest+1;
|
||||
@ -454,6 +459,7 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,
|
||||
QC_OUT_CHANNEL *qcOutChannel,
|
||||
SHORT *quantSpec,
|
||||
SHORT *quantSpecTmp,
|
||||
INT dZoneQuantEnable,
|
||||
INT *scf,
|
||||
INT *minScf,
|
||||
FIXP_DBL *sfbDist,
|
||||
@ -570,7 +576,8 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,
|
||||
sfbDistNew = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs,
|
||||
quantSpecTmp+sfbOffs,
|
||||
sfbWidth,
|
||||
scfAct);
|
||||
scfAct,
|
||||
dZoneQuantEnable);
|
||||
|
||||
if (sfbDistNew < sfbDist[sfbAct]) {
|
||||
/* success, replace scf by new one */
|
||||
@ -629,6 +636,7 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan,
|
||||
QC_OUT_CHANNEL *qcOutChannel,
|
||||
SHORT *quantSpec,
|
||||
SHORT *quantSpecTmp,
|
||||
INT dZoneQuantEnable,
|
||||
INT *scf,
|
||||
INT *minScf,
|
||||
FIXP_DBL *sfbDist,
|
||||
@ -724,7 +732,8 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan,
|
||||
sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs,
|
||||
quantSpecTmp+sfbOffs,
|
||||
sfbWidth,
|
||||
scfAct);
|
||||
scfAct,
|
||||
dZoneQuantEnable);
|
||||
|
||||
if (sfbDistNew[sfb] >qcOutChannel->sfbThresholdLdData[sfb]) {
|
||||
/* no improvement, skip further dist. calculations */
|
||||
@ -768,6 +777,7 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh
|
||||
QC_OUT_CHANNEL *qcOutChannel,
|
||||
SHORT *quantSpec,
|
||||
SHORT *quantSpecTmp,
|
||||
INT dZoneQuantEnable,
|
||||
INT *scf,
|
||||
INT *minScf,
|
||||
FIXP_DBL *sfbDist,
|
||||
@ -883,7 +893,8 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh
|
||||
sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb],
|
||||
quantSpecTmp+sfbOffs[sfb],
|
||||
sfbOffs[sfb+1]-sfbOffs[sfb],
|
||||
scfNew);
|
||||
scfNew,
|
||||
dZoneQuantEnable);
|
||||
|
||||
if (sfbDistNew[sfb] > sfbDistMax[sfb]) {
|
||||
/* no improvement, skip further dist. calculations */
|
||||
@ -963,7 +974,8 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh
|
||||
sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb],
|
||||
quantSpecTmp+sfbOffs[sfb],
|
||||
sfbOffs[sfb+1]-sfbOffs[sfb],
|
||||
scfNew);
|
||||
scfNew,
|
||||
dZoneQuantEnable);
|
||||
|
||||
if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) {
|
||||
/* no improvement, skip further dist. calculations */
|
||||
@ -1058,7 +1070,8 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel,
|
||||
INT *RESTRICT globalGain,
|
||||
FIXP_DBL *RESTRICT sfbFormFactorLdData
|
||||
,const INT invQuant,
|
||||
SHORT *RESTRICT quantSpec
|
||||
SHORT *RESTRICT quantSpec,
|
||||
const INT dZoneQuantEnable
|
||||
)
|
||||
{
|
||||
INT i, j, sfb, sfbOffs;
|
||||
@ -1160,7 +1173,8 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel,
|
||||
quantSpecTmp+psyOutChannel->sfbOffsets[sfbOffs+sfb],
|
||||
psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb],
|
||||
threshLdData, scfInt, minSfMaxQuant[sfbOffs+sfb],
|
||||
&sfbDistLdData[sfbOffs+sfb], &minScfCalculated[sfbOffs+sfb]
|
||||
&sfbDistLdData[sfbOffs+sfb], &minScfCalculated[sfbOffs+sfb],
|
||||
dZoneQuantEnable
|
||||
);
|
||||
}
|
||||
scf[sfbOffs+sfb] = scfInt;
|
||||
@ -1187,20 +1201,32 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel,
|
||||
sfbNRelevantLines);
|
||||
|
||||
|
||||
FDKaacEnc_assimilateSingleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, scf,
|
||||
FDKaacEnc_assimilateSingleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
|
||||
dZoneQuantEnable,
|
||||
scf,
|
||||
minSfMaxQuant, sfbDistLdData, sfbConstPePart,
|
||||
sfbFormFactorLdData, sfbNRelevantLines, minScfCalculated, 1);
|
||||
|
||||
if(invQuant > 1) {
|
||||
FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
|
||||
dZoneQuantEnable,
|
||||
scf,
|
||||
minSfMaxQuant, sfbDistLdData, sfbConstPePart,
|
||||
sfbFormFactorLdData, sfbNRelevantLines);
|
||||
|
||||
FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, scf,
|
||||
minSfMaxQuant, sfbDistLdData, sfbConstPePart,
|
||||
sfbFormFactorLdData, sfbNRelevantLines);
|
||||
FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
|
||||
dZoneQuantEnable,
|
||||
scf,
|
||||
minSfMaxQuant, sfbDistLdData, sfbConstPePart,
|
||||
sfbFormFactorLdData, sfbNRelevantLines);
|
||||
|
||||
|
||||
FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, scf,
|
||||
minSfMaxQuant, sfbDistLdData, sfbConstPePart,
|
||||
sfbFormFactorLdData, sfbNRelevantLines);
|
||||
|
||||
FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
|
||||
dZoneQuantEnable,
|
||||
scf,
|
||||
minSfMaxQuant, sfbDistLdData, sfbConstPePart,
|
||||
sfbFormFactorLdData, sfbNRelevantLines);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1223,7 +1249,8 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel,
|
||||
FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+psyOutChannel->sfbOffsets[sfbOffs+sfb],
|
||||
quantSpec+psyOutChannel->sfbOffsets[sfbOffs+sfb],
|
||||
psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb],
|
||||
scf[sfbOffs+sfb]
|
||||
scf[sfbOffs+sfb],
|
||||
dZoneQuantEnable
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1281,6 +1308,7 @@ void
|
||||
FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
|
||||
QC_OUT_CHANNEL* qcOutChannel[],
|
||||
const int invQuant,
|
||||
const INT dZoneQuantEnable,
|
||||
const int nChannels)
|
||||
{
|
||||
int ch;
|
||||
@ -1293,7 +1321,8 @@ FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
|
||||
&qcOutChannel[ch]->globalGain,
|
||||
qcOutChannel[ch]->sfbFormFactorLdData
|
||||
,invQuant,
|
||||
qcOutChannel[ch]->quantSpec
|
||||
qcOutChannel[ch]->quantSpec,
|
||||
dZoneQuantEnable
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -110,6 +110,7 @@ void
|
||||
FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
|
||||
QC_OUT_CHANNEL* qcOutChannel[],
|
||||
const int invQuant,
|
||||
const INT dZoneQuantEnable,
|
||||
const int nChannels);
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -100,6 +100,7 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitrate,
|
||||
INT channels,
|
||||
INT blocktype,
|
||||
INT granuleLength,
|
||||
INT isLowDelay,
|
||||
INT ldSbrPresent,
|
||||
TNS_CONFIG *tnsConfig,
|
||||
PSY_CONFIGURATION *psyConfig,
|
||||
|
@ -94,6 +94,35 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
#include "common_fix.h"
|
||||
|
||||
#if !defined(FUNCTION_fIsLessThan)
|
||||
/**
|
||||
* \brief Compares two fixpoint values incl. scaling.
|
||||
* \param a_m mantissa of the first input value.
|
||||
* \param a_e exponent of the first input value.
|
||||
* \param b_m mantissa of the second input value.
|
||||
* \param b_e exponent of the second input value.
|
||||
* \return non-zero if (a_m*2^a_e) < (b_m*2^b_e), 0 otherwise
|
||||
*/
|
||||
FDK_INLINE INT fIsLessThan(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e)
|
||||
{
|
||||
if (a_e > b_e) {
|
||||
return (b_m >> fMin(a_e-b_e, DFRACT_BITS-1) > a_m);
|
||||
} else {
|
||||
return (a_m >> fMin(b_e-a_e, DFRACT_BITS-1) < b_m);
|
||||
}
|
||||
}
|
||||
|
||||
FDK_INLINE INT fIsLessThan(FIXP_SGL a_m, INT a_e, FIXP_SGL b_m, INT b_e)
|
||||
{
|
||||
if (a_e > b_e) {
|
||||
return (b_m >> fMin(a_e-b_e, FRACT_BITS-1) > a_m);
|
||||
} else {
|
||||
return (a_m >> fMin(b_e-a_e, FRACT_BITS-1) < b_m);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define LD_DATA_SCALING (64.0f)
|
||||
#define LD_DATA_SHIFT 6 /* pow(2, LD_DATA_SHIFT) = LD_DATA_SCALING */
|
||||
|
@ -93,7 +93,7 @@ amm-info@iis.fraunhofer.de
|
||||
/* FDK tools library info */
|
||||
#define FDK_TOOLS_LIB_VL0 2
|
||||
#define FDK_TOOLS_LIB_VL1 3
|
||||
#define FDK_TOOLS_LIB_VL2 4
|
||||
#define FDK_TOOLS_LIB_VL2 5
|
||||
#define FDK_TOOLS_LIB_TITLE "FDK Tools"
|
||||
#ifdef __ANDROID__
|
||||
#define FDK_TOOLS_LIB_BUILD_DATE ""
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -135,6 +135,12 @@ enum
|
||||
SBR_SYNTAX_DRM_CRC = 0x0008
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FREQ_RES_LOW = 0,
|
||||
FREQ_RES_HIGH
|
||||
} FREQ_RES;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CODEC_TYPE coreCoder; /*!< LC or ELD */
|
||||
@ -168,8 +174,9 @@ typedef struct sbrConfiguration
|
||||
INT dynBwSupported; /*!< Flag: support for dynamic bandwidth in this combination. */
|
||||
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
|
||||
0=1 Env; 1=2 Env; 2=4 Env; */
|
||||
FREQ_RES freq_res_fixfix[2];/*!< Frequency resolution of envelopes in frame class FIXFIX, for non-split case and split case */
|
||||
UCHAR fResTransIsLow; /*!< Frequency resolution of envelopes in transient frames: low (0) or variable (1) */
|
||||
|
||||
/*
|
||||
core coder dependent tuning parameters
|
||||
*/
|
||||
@ -221,6 +228,8 @@ typedef struct sbrConfiguration
|
||||
INT sbr_interpol_freq; /*!< Flag: use interpolation in freq. direction. */
|
||||
INT sbr_smoothing_length; /*!< Flag: choose length 4 or 0 (=on, off). */
|
||||
UCHAR init_amp_res_FF;
|
||||
FIXP_DBL threshold_AmpRes_FF_m;
|
||||
SCHAR threshold_AmpRes_FF_e;
|
||||
} sbrConfiguration, *sbrConfigurationPtr ;
|
||||
|
||||
typedef struct SBR_CONFIG_DATA
|
||||
@ -237,7 +246,7 @@ typedef struct SBR_CONFIG_DATA
|
||||
INT noQmfBands; /**< Number of QMF frequency bands. */
|
||||
INT noQmfSlots; /**< Number of QMF slots. */
|
||||
|
||||
UCHAR *freqBandTable[2]; /**< Frequency table for low and hires, only MAX_FREQ_COEFFS/2 +1 coeefs actually needed for lowres. */
|
||||
UCHAR *freqBandTable[2]; /**< Frequency table for low and hires, only MAX_FREQ_COEFFS/2 +1 coeffs actually needed for lowres. */
|
||||
UCHAR *v_k_master; /**< Master BandTable where freqBandTable is derived from. */
|
||||
|
||||
|
||||
@ -249,6 +258,8 @@ typedef struct SBR_CONFIG_DATA
|
||||
INT xposCtrlSwitch; /**< Flag indicates whether to switch xpos ctrl on the fly. */
|
||||
INT switchTransposers; /**< Flag indicates whether to switch xpos on the fly . */
|
||||
UCHAR initAmpResFF;
|
||||
FIXP_DBL thresholdAmpResFF_m;
|
||||
SCHAR thresholdAmpResFF_e;
|
||||
} SBR_CONFIG_DATA, *HANDLE_SBR_CONFIG_DATA;
|
||||
|
||||
typedef struct {
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -141,8 +141,8 @@ struct SBR_ENV_DATA
|
||||
{
|
||||
|
||||
INT sbr_xpos_ctrl;
|
||||
INT freq_res_fixfix;
|
||||
|
||||
FREQ_RES freq_res_fixfix[2];
|
||||
UCHAR fResTransIsLow;
|
||||
|
||||
INVF_MODE sbr_invf_mode;
|
||||
INVF_MODE sbr_invf_mode_vec[MAX_NUM_NOISE_VALUES];
|
||||
@ -205,6 +205,8 @@ struct SBR_ENV_DATA
|
||||
INT balance;
|
||||
AMP_RES init_sbr_amp_res;
|
||||
AMP_RES currentAmpResFF;
|
||||
FIXP_DBL ton_HF[SBR_GLOBAL_TONALITY_VALUES]; /* tonality is scaled by 2^19/0.524288f (fract part of RELAXATION) */
|
||||
FIXP_DBL global_tonality;
|
||||
|
||||
/* extended data */
|
||||
INT extended_data;
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -103,6 +103,114 @@ static const UCHAR panTable[2][10] = { { 0, 2, 4, 6, 8,12,16,20,24},
|
||||
static const UCHAR maxIndex[2] = {9, 5};
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
Functionname: FDKsbrEnc_GetTonality
|
||||
******************************************************************************/
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
\brief Calculates complete energy per band from the energy values
|
||||
of the QMF subsamples.
|
||||
|
||||
\brief quotaMatrix - calculated in FDKsbrEnc_CalculateTonalityQuotas()
|
||||
\brief noEstPerFrame - number of estimations per frame
|
||||
\brief startIndex - start index for the quota matrix
|
||||
\brief Energies - energy matrix
|
||||
\brief startBand - start band
|
||||
\brief stopBand - number of QMF bands
|
||||
\brief numberCols - number of QMF subsamples
|
||||
|
||||
\return mean tonality of the 5 bands with the highest energy
|
||||
scaled by 2^(RELAXATION_SHIFT+2)*RELAXATION_FRACT
|
||||
|
||||
****************************************************************************/
|
||||
static FIXP_DBL FDKsbrEnc_GetTonality(
|
||||
const FIXP_DBL *const *quotaMatrix,
|
||||
const INT noEstPerFrame,
|
||||
const INT startIndex,
|
||||
const FIXP_DBL *const *Energies,
|
||||
const UCHAR startBand,
|
||||
const INT stopBand,
|
||||
const INT numberCols
|
||||
)
|
||||
{
|
||||
UCHAR b, e, k;
|
||||
INT no_enMaxBand[SBR_MAX_ENERGY_VALUES] = { -1, -1, -1, -1, -1 };
|
||||
FIXP_DBL energyMax[SBR_MAX_ENERGY_VALUES] = { FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f) };
|
||||
FIXP_DBL energyMaxMin = MAXVAL_DBL; /* min. energy in energyMax array */
|
||||
UCHAR posEnergyMaxMin = 0; /* min. energy in energyMax array position */
|
||||
FIXP_DBL tonalityBand[SBR_MAX_ENERGY_VALUES] = { FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f) };
|
||||
FIXP_DBL globalTonality = FL2FXCONST_DBL(0.0f);
|
||||
FIXP_DBL energyBand[QMF_CHANNELS];
|
||||
INT maxNEnergyValues; /* max. number of max. energy values */
|
||||
|
||||
/*** Sum up energies for each band ***/
|
||||
FDK_ASSERT(numberCols==15||numberCols==16);
|
||||
/* numberCols is always 15 or 16 for ELD. In case of 16 bands, the
|
||||
energyBands are initialized with the [15]th column.
|
||||
The rest of the column energies are added in the next step. */
|
||||
if (numberCols==15) {
|
||||
for (b=startBand; b<stopBand; b++) {
|
||||
energyBand[b]=FL2FXCONST_DBL(0.0f);
|
||||
}
|
||||
} else {
|
||||
for (b=startBand; b<stopBand; b++) {
|
||||
energyBand[b]=Energies[15][b]>>4;
|
||||
}
|
||||
}
|
||||
|
||||
for (k=0; k<15; k++) {
|
||||
for (b=startBand; b<stopBand; b++) {
|
||||
energyBand[b] += Energies[k][b]>>4;
|
||||
}
|
||||
}
|
||||
|
||||
/*** Determine 5 highest band-energies ***/
|
||||
maxNEnergyValues = fMin(SBR_MAX_ENERGY_VALUES, stopBand-startBand);
|
||||
|
||||
/* Get min. value in energyMax array */
|
||||
energyMaxMin = energyMax[0] = energyBand[startBand];
|
||||
no_enMaxBand[0] = startBand;
|
||||
posEnergyMaxMin = 0;
|
||||
for (k=1; k<maxNEnergyValues; k++) {
|
||||
energyMax[k] = energyBand[startBand+k];
|
||||
no_enMaxBand[k] = startBand+k;
|
||||
if (energyMaxMin > energyMax[k]) {
|
||||
energyMaxMin = energyMax[k];
|
||||
posEnergyMaxMin = k;
|
||||
}
|
||||
}
|
||||
|
||||
for (b=startBand+maxNEnergyValues; b<stopBand; b++) {
|
||||
if (energyBand[b] > energyMaxMin) {
|
||||
energyMax[posEnergyMaxMin] = energyBand[b];
|
||||
no_enMaxBand[posEnergyMaxMin] = b;
|
||||
|
||||
/* Again, get min. value in energyMax array */
|
||||
energyMaxMin = energyMax[0];
|
||||
posEnergyMaxMin = 0;
|
||||
for (k=1; k<maxNEnergyValues; k++) {
|
||||
if (energyMaxMin > energyMax[k]) {
|
||||
energyMaxMin = energyMax[k];
|
||||
posEnergyMaxMin = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*** End determine 5 highest band-energies ***/
|
||||
|
||||
/* Get tonality values for 5 highest energies */
|
||||
for (e=0; e<maxNEnergyValues; e++) {
|
||||
tonalityBand[e]=FL2FXCONST_DBL(0.0f);
|
||||
for (k=0; k<noEstPerFrame; k++) {
|
||||
tonalityBand[e] += quotaMatrix[startIndex + k][no_enMaxBand[e]] >> 1;
|
||||
}
|
||||
globalTonality += tonalityBand[e] >> 2; /* headroom of 2+1 (max. 5 additions) */
|
||||
}
|
||||
|
||||
return globalTonality;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/*!
|
||||
|
||||
@ -919,10 +1027,42 @@ FDKsbrEnc_extractSbrEnvelope1 (
|
||||
hEnvChan->qmfScale);
|
||||
|
||||
|
||||
if(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
|
||||
FIXP_DBL tonality = FDKsbrEnc_GetTonality (
|
||||
hEnvChan->TonCorr.quotaMatrix,
|
||||
hEnvChan->TonCorr.numberOfEstimatesPerFrame,
|
||||
hEnvChan->TonCorr.startIndexMatrix,
|
||||
sbrExtrEnv->YBuffer + sbrExtrEnv->YBufferWriteOffset,
|
||||
h_con->freqBandTable[HI][0]+1,
|
||||
h_con->noQmfBands,
|
||||
sbrExtrEnv->no_cols
|
||||
);
|
||||
|
||||
hEnvChan->encEnvData.ton_HF[1] = hEnvChan->encEnvData.ton_HF[0];
|
||||
hEnvChan->encEnvData.ton_HF[0] = tonality;
|
||||
|
||||
/* tonality is scaled by 2^19/0.524288f (fract part of RELAXATION) */
|
||||
hEnvChan->encEnvData.global_tonality = (hEnvChan->encEnvData.ton_HF[0]>>1) + (hEnvChan->encEnvData.ton_HF[1]>>1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Transient detection COEFF Transform OK
|
||||
*/
|
||||
if(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
|
||||
{
|
||||
FDKsbrEnc_fastTransientDetect(
|
||||
&hEnvChan->sbrFastTransientDetector,
|
||||
sbrExtrEnv->YBuffer,
|
||||
sbrExtrEnv->YBufferScale,
|
||||
sbrExtrEnv->YBufferWriteOffset,
|
||||
eData->transient_info
|
||||
);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
FDKsbrEnc_transientDetect(&hEnvChan->sbrTransientDetector,
|
||||
sbrExtrEnv->YBuffer,
|
||||
sbrExtrEnv->YBufferScale,
|
||||
@ -931,6 +1071,7 @@ FDKsbrEnc_extractSbrEnvelope1 (
|
||||
sbrExtrEnv->YBufferSzShift,
|
||||
sbrExtrEnv->time_step,
|
||||
hEnvChan->SbrEnvFrame.frameMiddleSlot);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -951,7 +1092,8 @@ FDKsbrEnc_extractSbrEnvelope1 (
|
||||
sbrExtrEnv->YBufferSzShift,
|
||||
h_con->nSfb[1],
|
||||
sbrExtrEnv->time_step,
|
||||
sbrExtrEnv->no_cols);
|
||||
sbrExtrEnv->no_cols,
|
||||
&hEnvChan->encEnvData.global_tonality);
|
||||
|
||||
|
||||
}
|
||||
@ -1128,12 +1270,26 @@ FDKsbrEnc_extractSbrEnvelope2 (
|
||||
&& ( ed->nEnvelopes == 1 ) )
|
||||
{
|
||||
|
||||
if (hEnvChan->encEnvData.ldGrid)
|
||||
hEnvChan->encEnvData.currentAmpResFF = (AMP_RES)h_con->initAmpResFF;
|
||||
else
|
||||
if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
|
||||
{
|
||||
/* Note: global_tonaliy_float_value == ((float)hEnvChan->encEnvData.global_tonality/((INT64)(1)<<(31-(19+2)))/0.524288*(2.0/3.0)));
|
||||
threshold_float_value == ((float)h_con->thresholdAmpResFF_m/((INT64)(1)<<(31-(h_con->thresholdAmpResFF_e)))/0.524288*(2.0/3.0))); */
|
||||
/* decision of SBR_AMP_RES */
|
||||
if (fIsLessThan( /* global_tonality > threshold ? */
|
||||
h_con->thresholdAmpResFF_m, h_con->thresholdAmpResFF_e,
|
||||
hEnvChan->encEnvData.global_tonality, RELAXATION_SHIFT+2 )
|
||||
)
|
||||
{
|
||||
hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
|
||||
}
|
||||
else {
|
||||
hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0;
|
||||
}
|
||||
} else {
|
||||
hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
|
||||
}
|
||||
|
||||
if ( hEnvChan->encEnvData.currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) {
|
||||
if ( hEnvChan->encEnvData.currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) {
|
||||
|
||||
FDKsbrEnc_InitSbrHuffmanTables(&hEnvChan->encEnvData,
|
||||
&hEnvChan->sbrCodeEnvelope,
|
||||
@ -1172,7 +1328,12 @@ FDKsbrEnc_extractSbrEnvelope2 (
|
||||
}
|
||||
|
||||
/* Low energy in low band fix */
|
||||
if ( hEnvChan->sbrTransientDetector.prevLowBandEnergy < hEnvChan->sbrTransientDetector.prevHighBandEnergy && hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03))
|
||||
if ( hEnvChan->sbrTransientDetector.prevLowBandEnergy < hEnvChan->sbrTransientDetector.prevHighBandEnergy
|
||||
&& hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03)
|
||||
/* The fix needs the non-fast transient detector running.
|
||||
It sets prevLowBandEnergy and prevHighBandEnergy. */
|
||||
&& !(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
|
||||
)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -127,6 +127,7 @@ typedef SBR_EXTRACT_ENVELOPE *HANDLE_SBR_EXTRACT_ENVELOPE;
|
||||
|
||||
struct ENV_CHANNEL
|
||||
{
|
||||
FAST_TRAN_DETECTOR sbrFastTransientDetector;
|
||||
SBR_TRANSIENT_DETECTOR sbrTransientDetector;
|
||||
SBR_CODE_ENVELOPE sbrCodeEnvelope;
|
||||
SBR_CODE_ENVELOPE sbrCodeNoiseFloor;
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -266,7 +266,7 @@ static void calcCtrlSignal (HANDLE_SBR_GRID hSbrGrid, FRAME_CLASS frameClass,
|
||||
|
||||
static void ctrlSignal2FrameInfo (HANDLE_SBR_GRID hSbrGrid,
|
||||
HANDLE_SBR_FRAME_INFO hFrameInfo,
|
||||
INT freq_res_fixfix);
|
||||
FREQ_RES *freq_res_fixfix);
|
||||
|
||||
|
||||
/* table for 8 time slot index */
|
||||
@ -341,8 +341,9 @@ static const FREQ_RES freqRes_table_16[16] = {
|
||||
static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
|
||||
HANDLE_SBR_GRID hSbrGrid,
|
||||
int tranPosInternal,
|
||||
int numberTimeSlots
|
||||
);
|
||||
int numberTimeSlots,
|
||||
UCHAR fResTransIsLow
|
||||
);
|
||||
|
||||
|
||||
/*!
|
||||
@ -402,11 +403,10 @@ FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
|
||||
const int *v_tuningFreq = v_tuning + 3;
|
||||
|
||||
hSbrEnvFrame->v_tuningSegm = v_tuningSegm;
|
||||
INT freq_res_fixfix = hSbrEnvFrame->freq_res_fixfix;
|
||||
|
||||
if (ldGrid) {
|
||||
/* in case there was a transient at the very end of the previous frame, start with a transient envelope */
|
||||
if(v_transient_info_pre[1] && (numberTimeSlots - v_transient_info_pre[0] < minFrameTranDistance)){
|
||||
if ( !tranFlag && v_transient_info_pre[1] && (numberTimeSlots - v_transient_info_pre[0] < minFrameTranDistance) ){
|
||||
tranFlag = 1;
|
||||
tranPos = 0;
|
||||
}
|
||||
@ -529,7 +529,8 @@ FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
|
||||
generateFixFixOnly ( &(hSbrEnvFrame->SbrFrameInfo),
|
||||
&(hSbrEnvFrame->SbrGrid),
|
||||
tranPosInternal,
|
||||
numberTimeSlots
|
||||
numberTimeSlots,
|
||||
hSbrEnvFrame->fResTransIsLow
|
||||
);
|
||||
|
||||
return &(hSbrEnvFrame->SbrFrameInfo);
|
||||
@ -677,7 +678,7 @@ FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
|
||||
---------------------------------------------------------------------------*/
|
||||
ctrlSignal2FrameInfo (&hSbrEnvFrame->SbrGrid,
|
||||
&hSbrEnvFrame->SbrFrameInfo,
|
||||
freq_res_fixfix);
|
||||
hSbrEnvFrame->freq_res_fixfix);
|
||||
|
||||
return &hSbrEnvFrame->SbrFrameInfo;
|
||||
}
|
||||
@ -692,7 +693,8 @@ FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
|
||||
static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
|
||||
HANDLE_SBR_GRID hSbrGrid,
|
||||
int tranPosInternal,
|
||||
int numberTimeSlots
|
||||
int numberTimeSlots,
|
||||
UCHAR fResTransIsLow
|
||||
)
|
||||
{
|
||||
int nEnv, i, k=0, tranIdx;
|
||||
@ -727,8 +729,12 @@ static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
|
||||
/* adjust segment-frequency-resolution according to the segment-length */
|
||||
for (i=0; i<nEnv; i++){
|
||||
k = hSbrFrameInfo->borders[i+1] - hSbrFrameInfo->borders[i];
|
||||
hSbrFrameInfo->freqRes[i] = freqResTable[k];
|
||||
hSbrGrid->v_f[i] = freqResTable[k];
|
||||
if (!fResTransIsLow)
|
||||
hSbrFrameInfo->freqRes[i] = freqResTable[k];
|
||||
else
|
||||
hSbrFrameInfo->freqRes[i] = FREQ_RES_LOW;
|
||||
|
||||
hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i];
|
||||
}
|
||||
|
||||
hSbrFrameInfo->nEnvelopes = nEnv;
|
||||
@ -765,15 +771,16 @@ static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
|
||||
|
||||
*******************************************************************************/
|
||||
void
|
||||
FDKsbrEnc_initFrameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
|
||||
INT allowSpread,
|
||||
INT numEnvStatic,
|
||||
INT staticFraming,
|
||||
INT timeSlots,
|
||||
INT freq_res_fixfix
|
||||
,int ldGrid
|
||||
)
|
||||
|
||||
FDKsbrEnc_initFrameInfoGenerator (
|
||||
HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
|
||||
INT allowSpread,
|
||||
INT numEnvStatic,
|
||||
INT staticFraming,
|
||||
INT timeSlots,
|
||||
const FREQ_RES* freq_res_fixfix
|
||||
,UCHAR fResTransIsLow,
|
||||
INT ldGrid
|
||||
)
|
||||
{ /* FH 00-06-26 */
|
||||
|
||||
FDKmemclear(hSbrEnvFrame,sizeof(SBR_ENVELOPE_FRAME ));
|
||||
@ -786,7 +793,9 @@ FDKsbrEnc_initFrameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
|
||||
hSbrEnvFrame->allowSpread = allowSpread;
|
||||
hSbrEnvFrame->numEnvStatic = numEnvStatic;
|
||||
hSbrEnvFrame->staticFraming = staticFraming;
|
||||
hSbrEnvFrame->freq_res_fixfix = freq_res_fixfix;
|
||||
hSbrEnvFrame->freq_res_fixfix[0] = freq_res_fixfix[0];
|
||||
hSbrEnvFrame->freq_res_fixfix[1] = freq_res_fixfix[1];
|
||||
hSbrEnvFrame->fResTransIsLow = fResTransIsLow;
|
||||
|
||||
hSbrEnvFrame->length_v_bord = 0;
|
||||
hSbrEnvFrame->length_v_bordFollow = 0;
|
||||
@ -804,6 +813,7 @@ FDKsbrEnc_initFrameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
|
||||
hSbrEnvFrame->dmin = 2;
|
||||
hSbrEnvFrame->dmax = 16;
|
||||
hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_512LD;
|
||||
hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
|
||||
} else
|
||||
switch(timeSlots){
|
||||
case NUMBER_TIME_SLOTS_1920:
|
||||
@ -1862,19 +1872,28 @@ createDefFrameInfo(HANDLE_SBR_FRAME_INFO hSbrFrameInfo, INT nEnv, INT nTimeSlots
|
||||
Functionname: ctrlSignal2FrameInfo
|
||||
*******************************************************************************
|
||||
|
||||
Description: Calculates frame_info struct from control signal.
|
||||
Description: Convert "clear-text" sbr_grid() to "frame info" used by the
|
||||
envelope and noise floor estimators.
|
||||
This is basically (except for "low level" calculations) the
|
||||
bitstream decoder defined in the MPEG-4 standard, sub clause
|
||||
4.6.18.3.3, Time / Frequency Grid. See inline comments for
|
||||
explanation of the shorten and noise border algorithms.
|
||||
|
||||
Arguments: hSbrGrid - source
|
||||
hSbrFrameInfo - destination
|
||||
freq_res_fixfix - frequency resolution for FIXFIX frames
|
||||
|
||||
Return: void; hSbrFrameInfo contains the updated FRAME_INFO struct
|
||||
|
||||
*******************************************************************************/
|
||||
static void
|
||||
ctrlSignal2FrameInfo (HANDLE_SBR_GRID hSbrGrid,
|
||||
HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
|
||||
INT freq_res_fixfix)
|
||||
ctrlSignal2FrameInfo (
|
||||
HANDLE_SBR_GRID hSbrGrid, /* input : the grid handle */
|
||||
HANDLE_SBR_FRAME_INFO hSbrFrameInfo, /* output: the frame info handle */
|
||||
FREQ_RES *freq_res_fixfix /* in/out: frequency resolution for FIXFIX frames */
|
||||
)
|
||||
{
|
||||
INT frameSplit = 0;
|
||||
INT nEnv = 0, border = 0, i, k, p /*?*/;
|
||||
INT *v_r = hSbrGrid->bs_rel_bord;
|
||||
INT *v_f = hSbrGrid->v_f;
|
||||
@ -1887,17 +1906,10 @@ ctrlSignal2FrameInfo (HANDLE_SBR_GRID hSbrGrid,
|
||||
case FIXFIX:
|
||||
createDefFrameInfo(hSbrFrameInfo, hSbrGrid->bs_num_env, numberTimeSlots);
|
||||
|
||||
/* At this point all frequency resolutions are set to FREQ_RES_HIGH, so
|
||||
* only if freq_res_fixfix is set to FREQ_RES_LOW, they all have to be
|
||||
* changed.
|
||||
* snd */
|
||||
if (freq_res_fixfix == FREQ_RES_LOW) {
|
||||
for (i = 0; i < hSbrFrameInfo->nEnvelopes; i++) {
|
||||
hSbrFrameInfo->freqRes[i] = FREQ_RES_LOW;
|
||||
}
|
||||
frameSplit = (hSbrFrameInfo->nEnvelopes > 1);
|
||||
for (i = 0; i < hSbrFrameInfo->nEnvelopes; i++) {
|
||||
hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i] = freq_res_fixfix[frameSplit];
|
||||
}
|
||||
/* ELD: store current frequency resolution */
|
||||
hSbrGrid->v_f[0] = hSbrFrameInfo->freqRes[0];
|
||||
break;
|
||||
|
||||
case FIXVAR:
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -89,6 +89,7 @@ amm-info@iis.fraunhofer.de
|
||||
#define _FRAM_GEN_H
|
||||
|
||||
#include "sbr_def.h" /* for MAX_ENVELOPES and MAX_NOISE_ENVELOPES in struct FRAME_INFO and CODEC_TYPE */
|
||||
#include "sbr_encoder.h" /* for FREQ_RES */
|
||||
|
||||
#define MAX_ENVELOPES_VARVAR MAX_ENVELOPES /*!< worst case number of envelopes in a VARVAR frame */
|
||||
#define MAX_ENVELOPES_FIXVAR_VARFIX 4 /*!< worst case number of envelopes in VARFIX and FIXVAR frames */
|
||||
@ -114,7 +115,7 @@ typedef enum {
|
||||
#define NUMBER_TIME_SLOTS_1920 15
|
||||
|
||||
#define LD_PRETRAN_OFF 3
|
||||
#define FRAME_MIDDLE_SLOT_512LD 0
|
||||
#define FRAME_MIDDLE_SLOT_512LD 4
|
||||
#define NUMBER_TIME_SLOTS_512LD 8
|
||||
#define TRANSIENT_OFFSET_LD 0
|
||||
|
||||
@ -248,9 +249,10 @@ typedef struct
|
||||
INT frameMiddleSlot; /*!< transient detector offset in SBR timeslots */
|
||||
|
||||
/* basic tuning parameters */
|
||||
INT staticFraming; /*!< 1: run static framing in time, i.e. exclusive use of bs_frame_class = FIXFIX */
|
||||
INT numEnvStatic; /*!< number of envelopes per frame for static framing */
|
||||
INT freq_res_fixfix; /*!< envelope frequency resolution to use for bs_frame_class = FIXFIX */
|
||||
INT staticFraming; /*!< 1: run static framing in time, i.e. exclusive use of bs_frame_class = FIXFIX */
|
||||
INT numEnvStatic; /*!< number of envelopes per frame for static framing */
|
||||
FREQ_RES freq_res_fixfix[2]; /*!< envelope frequency resolution to use for bs_frame_class = FIXFIX; single env and split */
|
||||
UCHAR fResTransIsLow; /*!< frequency resolution for transient frames - always low (0) or according to table (1) */
|
||||
|
||||
/* expert tuning parameters */
|
||||
const int *v_tuningSegm; /*!< segment lengths to use around transient */
|
||||
@ -286,14 +288,16 @@ typedef SBR_ENVELOPE_FRAME *HANDLE_SBR_ENVELOPE_FRAME;
|
||||
|
||||
|
||||
void
|
||||
FDKsbrEnc_initFrameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
|
||||
INT allowSpread,
|
||||
INT numEnvStatic,
|
||||
INT staticFraming,
|
||||
INT timeSlots,
|
||||
INT freq_res_fixfix
|
||||
,int ldGrid
|
||||
);
|
||||
FDKsbrEnc_initFrameInfoGenerator (
|
||||
HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
|
||||
INT allowSpread,
|
||||
INT numEnvStatic,
|
||||
INT staticFraming,
|
||||
INT timeSlots,
|
||||
const FREQ_RES* freq_res_fixfix
|
||||
,UCHAR fResTransIsLow,
|
||||
INT ldGrid
|
||||
);
|
||||
|
||||
HANDLE_SBR_FRAME_INFO
|
||||
FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -663,10 +663,27 @@ static void transientCleanUp(FIXP_DBL **quotaBuffer,
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/*!
|
||||
\brief Do detection for one tonality estimate.
|
||||
\brief Detection for one tonality estimate.
|
||||
|
||||
This is the actual missing harmonics detection, using information from the
|
||||
previous detection.
|
||||
|
||||
If a missing harmonic was detected (in a previous frame) due to too high
|
||||
tonality differences, but there was not enough tonality difference in the
|
||||
current frame, the detection algorithm still continues to trace the strongest
|
||||
tone in the scalefactor band (assuming that this is the tone that is going to
|
||||
be replaced in the decoder). This is done to avoid abrupt endings of sines
|
||||
fading out (e.g. in the glockenspiel).
|
||||
|
||||
The function also tries to estimate where one sine is going to be replaced
|
||||
with multiple sines (due to the patching). This is done by comparing the
|
||||
tonality flatness measure of the original and the SBR signal.
|
||||
|
||||
The function also tries to estimate (for the scalefactor bands only
|
||||
containing one qmf subband) when a strong tone in the original will be
|
||||
replaced by a strong tone in the adjacent QMF subband.
|
||||
|
||||
\return none.
|
||||
|
||||
@ -694,10 +711,10 @@ static void detection(FIXP_DBL *quotaBuffer,
|
||||
for(i=0;i<nSfb;i++){
|
||||
|
||||
thresTemp = (guideVectors.guideVectorDiff[i] != FL2FXCONST_DBL(0.0f))
|
||||
? fixMax(fMult(mhThresh.decayGuideDiff,guideVectors.guideVectorDiff[i]), mhThresh.thresHoldDiffGuide)
|
||||
? fMax(fMult(mhThresh.decayGuideDiff,guideVectors.guideVectorDiff[i]), mhThresh.thresHoldDiffGuide)
|
||||
: mhThresh.thresHoldDiff;
|
||||
|
||||
thresTemp = fixMin(thresTemp, mhThresh.thresHoldDiff);
|
||||
thresTemp = fMin(thresTemp, mhThresh.thresHoldDiff);
|
||||
|
||||
if(pDiffVecScfb[i] > thresTemp){
|
||||
pHarmVec[i] = 1;
|
||||
@ -813,8 +830,11 @@ static void detectionWithPrediction(FIXP_DBL **quotaBuffer,
|
||||
|
||||
if(newDetectionAllowed){
|
||||
|
||||
/* Since we don't want to use the transient region for detection (since the tonality values
|
||||
tend to be a bit unreliable for this region) the guide-values are copied to the current
|
||||
starting point. */
|
||||
if(totNoEst > 1){
|
||||
start = detectionStart;
|
||||
start = detectionStart+1;
|
||||
|
||||
if (start != 0) {
|
||||
FDKmemcpy(guideVectors[start].guideVectorDiff,guideVectors[0].guideVectorDiff,nSfb*sizeof(FIXP_DBL));
|
||||
|
@ -298,7 +298,7 @@ FDKsbrEnc_sbrNoiseFloorEstimateQmf(HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoiseFlo
|
||||
SCHAR *indexVector, /*!< Index vector to obtain the patched data. */
|
||||
INT missingHarmonicsFlag, /*!< Flag indicating if a strong tonal component will be missing. */
|
||||
INT startIndex, /*!< Start index. */
|
||||
int numberOfEstimatesPerFrame, /*!< The number of tonality estimates per frame. */
|
||||
UINT numberOfEstimatesPerFrame, /*!< The number of tonality estimates per frame. */
|
||||
int transientFrame, /*!< A flag indicating if a transient is present. */
|
||||
INVF_MODE* pInvFiltLevels, /*!< Pointer to the vector holding the inverse filtering levels. */
|
||||
UINT sbrSyntaxFlags
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -119,7 +119,7 @@ FDKsbrEnc_sbrNoiseFloorEstimateQmf(HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoiseFlo
|
||||
SCHAR* indexVector, /*!< Index vector to obtain the patched data. */
|
||||
INT missingHarmonicsFlag, /*!< Flag indicating if a strong tonal component will be missing. */
|
||||
INT startIndex, /*!< Start index. */
|
||||
int numberOfEstimatesPerFrame, /*!< The number of tonality estimates per frame. */
|
||||
UINT numberOfEstimatesPerFrame, /*!< The number of tonality estimates per frame. */
|
||||
INT transientFrame, /*!< A flag indicating if a transient is present. */
|
||||
INVF_MODE* pInvFiltLevels, /*!< Pointer to the vector holding the inverse filtering levels. */
|
||||
UINT sbrSyntaxFlags
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -122,6 +122,8 @@ amm-info@iis.fraunhofer.de
|
||||
/************ Definitions ***************/
|
||||
#define SBR_COMP_MODE_DELTA 0
|
||||
#define SBR_COMP_MODE_CTS 1
|
||||
#define SBR_MAX_ENERGY_VALUES 5
|
||||
#define SBR_GLOBAL_TONALITY_VALUES 2
|
||||
|
||||
#define MAX_NUM_CHANNELS 2
|
||||
|
||||
@ -232,6 +234,8 @@ amm-info@iis.fraunhofer.de
|
||||
#define FREQ 0
|
||||
#define TIME 1
|
||||
|
||||
/* qmf data scaling */
|
||||
#define QMF_SCALE_OFFSET 7
|
||||
|
||||
/* huffman tables */
|
||||
#define CODE_BOOK_SCF_LAV00 60
|
||||
@ -268,12 +272,4 @@ typedef enum
|
||||
}
|
||||
INVF_MODE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FREQ_RES_LOW = 0,
|
||||
FREQ_RES_HIGH
|
||||
}
|
||||
FREQ_RES;
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -103,7 +103,7 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
#define SBRENCODER_LIB_VL0 3
|
||||
#define SBRENCODER_LIB_VL1 3
|
||||
#define SBRENCODER_LIB_VL2 8
|
||||
#define SBRENCODER_LIB_VL2 12
|
||||
|
||||
|
||||
|
||||
@ -412,6 +412,23 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
|
||||
config->codecSettings.transFac = transFac;
|
||||
config->codecSettings.standardBitrate = standardBitrate;
|
||||
|
||||
if (bitRate < 28000) {
|
||||
config->threshold_AmpRes_FF_m = (FIXP_DBL)MAXVAL_DBL;
|
||||
config->threshold_AmpRes_FF_e = 7;
|
||||
}
|
||||
else if (bitRate >= 28000 && bitRate <= 48000) {
|
||||
/* The float threshold is 75
|
||||
0.524288f is fractional part of RELAXATION, the quotaMatrix and therefore tonality are scaled by this
|
||||
2/3 is because the original implementation divides the tonality values by 3, here it's divided by 2
|
||||
128 compensates the necessary shiftfactor of 7 */
|
||||
config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(75.0f*0.524288f/(2.0f/3.0f)/128.0f);
|
||||
config->threshold_AmpRes_FF_e = 7;
|
||||
}
|
||||
else if (bitRate > 48000) {
|
||||
config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(0);
|
||||
config->threshold_AmpRes_FF_e = 0;
|
||||
}
|
||||
|
||||
if (bitRate==0) {
|
||||
/* map vbr quality to bitrate */
|
||||
if (vbrMode < 30)
|
||||
@ -467,6 +484,57 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
|
||||
config->stereoMode = sbrTuningTable[idx].stereoMode ;
|
||||
config->freqScale = sbrTuningTable[idx].freqScale ;
|
||||
|
||||
if (numChannels == 1) {
|
||||
/* stereo case */
|
||||
switch (core) {
|
||||
case AOT_AAC_LC:
|
||||
if (bitRate <= (useSpeechConfig?24000U:20000U)) {
|
||||
config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
|
||||
config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
|
||||
}
|
||||
break;
|
||||
case AOT_ER_AAC_ELD:
|
||||
if (bitRate < 36000)
|
||||
config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
|
||||
if (bitRate < 26000) {
|
||||
config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
|
||||
config->fResTransIsLow = 1; /* for transient frames, set low frequency resolution */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* stereo case */
|
||||
switch (core) {
|
||||
case AOT_AAC_LC:
|
||||
if (bitRate <= 28000) {
|
||||
config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
|
||||
config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
|
||||
}
|
||||
break;
|
||||
case AOT_ER_AAC_ELD:
|
||||
if (bitRate < 72000) {
|
||||
config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
|
||||
}
|
||||
if (bitRate < 52000) {
|
||||
config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
|
||||
config->fResTransIsLow = 1; /* for transient frames, set low frequency resolution */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (bitRate <= 28000) {
|
||||
/*
|
||||
additionally restrict frequency resolution in FIXFIX frames
|
||||
to further reduce SBR payload size */
|
||||
config->freq_res_fixfix[0] = FREQ_RES_LOW;
|
||||
config->freq_res_fixfix[1] = FREQ_RES_LOW;
|
||||
}
|
||||
}
|
||||
|
||||
/* adjust usage of parametric coding dependent on bitrate and speech config flag */
|
||||
if (useSpeechConfig)
|
||||
config->parametricCoding = 0;
|
||||
@ -515,6 +583,7 @@ static UINT
|
||||
FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
|
||||
INT downSampleFactor,
|
||||
UINT codecGranuleLen
|
||||
,const INT isLowDelay
|
||||
)
|
||||
{
|
||||
if ( (downSampleFactor < 1 || downSampleFactor > 2) ||
|
||||
@ -525,7 +594,11 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
|
||||
config->useWaveCoding = 0;
|
||||
config->crcSbr = 0;
|
||||
config->dynBwSupported = 1;
|
||||
config->tran_thr = 13000;
|
||||
if (isLowDelay)
|
||||
config->tran_thr = 6000;
|
||||
else
|
||||
config->tran_thr = 13000;
|
||||
|
||||
config->parametricCoding = 1;
|
||||
|
||||
config->sbrFrameSize = codecGranuleLen * downSampleFactor;
|
||||
@ -558,7 +631,9 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
|
||||
config->noiseFloorOffset = 0;
|
||||
config->startFreq = 5; /* 5.9 respectively 6.0 kHz at fs = 44.1/48 kHz */
|
||||
config->stopFreq = 9; /* 16.2 respectively 16.8 kHz at fs = 44.1/48 kHz */
|
||||
|
||||
config->freq_res_fixfix[0] = FREQ_RES_HIGH; /* non-split case */
|
||||
config->freq_res_fixfix[1] = FREQ_RES_HIGH; /* split case */
|
||||
config->fResTransIsLow = 0; /* for transient frames, set variable frequency resolution according to freqResTable */
|
||||
|
||||
/* header_extra_1 */
|
||||
config->freqScale = SBR_FREQ_SCALE_DEFAULT;
|
||||
@ -1206,7 +1281,10 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
|
||||
|
||||
FDK_ASSERT(params->e >= 0);
|
||||
|
||||
hEnv->encEnvData.freq_res_fixfix = 1;
|
||||
hEnv->encEnvData.freq_res_fixfix[0] = params->freq_res_fixfix[0];
|
||||
hEnv->encEnvData.freq_res_fixfix[1] = params->freq_res_fixfix[1];
|
||||
hEnv->encEnvData.fResTransIsLow = params->fResTransIsLow;
|
||||
|
||||
hEnv->fLevelProtect = 0;
|
||||
|
||||
hEnv->encEnvData.ldGrid = (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? 1 : 0;
|
||||
@ -1348,11 +1426,29 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
|
||||
e,
|
||||
params->stat,
|
||||
timeSlots,
|
||||
hEnv->encEnvData.freq_res_fixfix
|
||||
,hEnv->encEnvData.ldGrid
|
||||
hEnv->encEnvData.freq_res_fixfix,
|
||||
hEnv->encEnvData.fResTransIsLow,
|
||||
hEnv->encEnvData.ldGrid
|
||||
);
|
||||
|
||||
if(sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
|
||||
{
|
||||
INT bandwidth_qmf_slot = (sbrConfigData->sampleFreq>>1) / (sbrConfigData->noQmfBands);
|
||||
if(FDKsbrEnc_InitSbrFastTransientDetector(
|
||||
&hEnv->sbrFastTransientDetector,
|
||||
sbrConfigData->noQmfSlots,
|
||||
bandwidth_qmf_slot,
|
||||
sbrConfigData->noQmfBands,
|
||||
sbrConfigData->freqBandTable[0][0]
|
||||
))
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* The transient detector has to be initialized also if the fast transient
|
||||
detector was active, because the values from the transient detector
|
||||
structure are used. */
|
||||
if(FDKsbrEnc_InitSbrTransientDetector (&hEnv->sbrTransientDetector,
|
||||
sbrConfigData->sbrSyntaxFlags,
|
||||
sbrConfigData->frameSize,
|
||||
sbrConfigData->sampleFreq,
|
||||
params,
|
||||
@ -1658,6 +1754,8 @@ INT FDKsbrEnc_EnvInit (
|
||||
/* other switches */
|
||||
hSbrElement->sbrConfigData.useWaveCoding = params->useWaveCoding;
|
||||
hSbrElement->sbrConfigData.useParametricCoding = params->parametricCoding;
|
||||
hSbrElement->sbrConfigData.thresholdAmpResFF_m = params->threshold_AmpRes_FF_m;
|
||||
hSbrElement->sbrConfigData.thresholdAmpResFF_e = params->threshold_AmpRes_FF_e;
|
||||
|
||||
/* init freq band table */
|
||||
if(updateFreqBandTable(&hSbrElement->sbrConfigData,
|
||||
@ -1999,7 +2097,8 @@ INT sbrEncoder_Init(
|
||||
*/
|
||||
if ( ! FDKsbrEnc_InitializeSbrDefaults ( &sbrConfig[el],
|
||||
*downSampleFactor,
|
||||
coreFrameLength
|
||||
coreFrameLength,
|
||||
IS_LOWDELAY(aot)
|
||||
) )
|
||||
{
|
||||
error = 1;
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -684,6 +684,9 @@ const sbrTuningTable_t sbrTuningTable[] =
|
||||
|
||||
/** AAC LOW DELAY SECTION **/
|
||||
|
||||
/* 24 kHz dual rate - 12kHz singlerate is not allowed (deactivated in FDKsbrEnc_IsSbrSettingAvail()) */
|
||||
{ CODEC_AACLD, 8000, 32000, 12000, 1, 1, 1, 0, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 8 kbit/s */
|
||||
|
||||
/*** 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 */
|
||||
@ -702,10 +705,10 @@ const sbrTuningTable_t sbrTuningTable[] =
|
||||
{ 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 */
|
||||
{ CODEC_AACLD, 20000, 22000, 24000, 1, 4, 1, 8, 4, 2, 3, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */
|
||||
{ CODEC_AACLD, 20000, 22000, 24000, 1, 3, 4, 8, 8, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */
|
||||
{ CODEC_AACLD, 22000, 28000, 24000, 1, 3, 8, 8, 7, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 24 kbit/s */
|
||||
{ CODEC_AACLD, 28000, 36000, 24000, 1, 4, 8, 8, 7, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */
|
||||
{ CODEC_AACLD, 36000, 56000, 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, 8, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */
|
||||
{ CODEC_AACLD, 56000, 64001, 24000, 1, 13,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 kbit/s */
|
||||
|
||||
/* 32/64 kHz dual rate */ /* placebo settings */ /*jgr: new, copy from CODEC_AAC */
|
||||
@ -722,7 +725,7 @@ const sbrTuningTable_t sbrTuningTable[] =
|
||||
{ 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, 36000, 60000, 48000, 1, 4, 7, 4, 4, 2, 0, 3, SBR_MONO, 3 }, /* 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 */
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -682,7 +682,7 @@ FDKsbrEnc_InitTonCorrParamExtr (INT frameSize, /*!< Current
|
||||
|
||||
/*
|
||||
Reset the patching and allocate memory for the quota matrix.
|
||||
Assing parameters for the LPC analysis.
|
||||
Assuming parameters for the LPC analysis.
|
||||
*/
|
||||
if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
|
||||
switch (timeSlots) {
|
||||
@ -690,7 +690,7 @@ FDKsbrEnc_InitTonCorrParamExtr (INT frameSize, /*!< Current
|
||||
hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
|
||||
hTonCorr->lpcLength[1] = 7 - LPC_ORDER;
|
||||
hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
|
||||
hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 7;
|
||||
hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 7 */
|
||||
hTonCorr->frameStartIndexInvfEst = 0;
|
||||
hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
|
||||
break;
|
||||
@ -698,7 +698,7 @@ FDKsbrEnc_InitTonCorrParamExtr (INT frameSize, /*!< Current
|
||||
hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
|
||||
hTonCorr->lpcLength[1] = 8 - LPC_ORDER;
|
||||
hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
|
||||
hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 8;
|
||||
hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 8 */
|
||||
hTonCorr->frameStartIndexInvfEst = 0;
|
||||
hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
|
||||
break;
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -118,7 +118,7 @@ typedef struct
|
||||
INT bufferLength; /*!< Length of the r and i buffers. */
|
||||
INT stepSize; /*!< Stride for the lpc estimate. */
|
||||
INT numberOfEstimates; /*!< The total number of estiamtes, available in the quotaMatrix.*/
|
||||
INT numberOfEstimatesPerFrame; /*!< The number of estimates per frame available in the quotaMatrix.*/
|
||||
UINT numberOfEstimatesPerFrame; /*!< The number of estimates per frame available in the quotaMatrix.*/
|
||||
INT lpcLength[2]; /*!< Segment length used for second order LPC analysis.*/
|
||||
INT nextSample; /*!< Where to start the LPC analysis of the current frame.*/
|
||||
INT move; /*!< How many estimates to move in the quotaMatrix, when buffering. */
|
||||
|
@ -89,7 +89,7 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
#include "genericStds.h"
|
||||
|
||||
#define NORM_QMF_ENERGY 5.684341886080801486968994140625e-14 /* 2^-44 */
|
||||
#define NORM_QMF_ENERGY 9.31322574615479E-10 /* 2^-30 */
|
||||
|
||||
/* static FIXP_DBL ABS_THRES = fixMax( FL2FXCONST_DBL(1.28e5 * NORM_QMF_ENERGY), (FIXP_DBL)1) Minimum threshold for detecting changes */
|
||||
#define ABS_THRES ((FIXP_DBL)16)
|
||||
@ -106,22 +106,30 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
\return calculated value
|
||||
*******************************************************************************/
|
||||
#define NRG_SHIFT 3 /* for energy summation */
|
||||
|
||||
static FIXP_DBL spectralChange(FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS],
|
||||
INT *scaleEnergies,
|
||||
FIXP_DBL EnergyTotal,
|
||||
INT nSfb,
|
||||
INT start,
|
||||
INT border,
|
||||
INT stop)
|
||||
INT YBufferWriteOffset,
|
||||
INT stop,
|
||||
INT *result_e)
|
||||
{
|
||||
INT i,j;
|
||||
INT len1,len2;
|
||||
FIXP_DBL delta,tmp0,tmp1,tmp2;
|
||||
FIXP_DBL accu1,accu2,delta_sum,result;
|
||||
SCHAR energies_e_diff[NUMBER_TIME_SLOTS_2304], energies_e, energyTotal_e=19, energies_e_add;
|
||||
SCHAR prevEnergies_e_diff, newEnergies_e_diff;
|
||||
FIXP_DBL tmp0,tmp1;
|
||||
FIXP_DBL accu1,accu2,accu1_init,accu2_init;
|
||||
FIXP_DBL delta, delta_sum;
|
||||
INT accu_e, tmp_e;
|
||||
|
||||
FDK_ASSERT(scaleEnergies[0] >= 0);
|
||||
delta_sum = FL2FXCONST_DBL(0.0f);
|
||||
*result_e = 0;
|
||||
|
||||
/* equal for aac (would be not equal for mp3) */
|
||||
len1 = border-start;
|
||||
len2 = stop-border;
|
||||
|
||||
@ -130,43 +138,91 @@ static FIXP_DBL spectralChange(FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FRE
|
||||
pos_weight = FL2FXCONST_DBL(0.5f) - (len1*GetInvInt(len1+len2));
|
||||
pos_weight = /*FL2FXCONST_DBL(1.0)*/ (FIXP_DBL)MAXVAL_DBL - (fMult(pos_weight, pos_weight)<<2);
|
||||
|
||||
delta_sum = FL2FXCONST_DBL(0.0f);
|
||||
/*** Calc scaling for energies ***/
|
||||
FDK_ASSERT(scaleEnergies[0] >= 0);
|
||||
FDK_ASSERT(scaleEnergies[1] >= 0);
|
||||
|
||||
energies_e = 19 - FDKmin(scaleEnergies[0], scaleEnergies[1]);
|
||||
|
||||
/* limit shift for energy accumulation, energies_e can be -10 min. */
|
||||
if (energies_e < -10) {
|
||||
energies_e_add = -10 - energies_e;
|
||||
energies_e = -10;
|
||||
} else if (energies_e > 17) {
|
||||
energies_e_add = energies_e - 17;
|
||||
energies_e = 17;
|
||||
} else {
|
||||
energies_e_add = 0;
|
||||
}
|
||||
|
||||
/* compensate scaling differences between scaleEnergies[0] and scaleEnergies[1] */
|
||||
prevEnergies_e_diff = scaleEnergies[0] - FDKmin(scaleEnergies[0], scaleEnergies[1]) + energies_e_add + NRG_SHIFT;
|
||||
newEnergies_e_diff = scaleEnergies[1] - FDKmin(scaleEnergies[0], scaleEnergies[1]) + energies_e_add + NRG_SHIFT;
|
||||
|
||||
prevEnergies_e_diff = fMin(prevEnergies_e_diff, DFRACT_BITS-1);
|
||||
newEnergies_e_diff = fMin(newEnergies_e_diff, DFRACT_BITS-1);
|
||||
|
||||
for (i=start; i<YBufferWriteOffset; i++) {
|
||||
energies_e_diff[i] = prevEnergies_e_diff;
|
||||
}
|
||||
for (i=YBufferWriteOffset; i<stop; i++) {
|
||||
energies_e_diff[i] = newEnergies_e_diff;
|
||||
}
|
||||
|
||||
/* Sum up energies of all QMF-timeslots for both halfs */
|
||||
FDK_ASSERT(len1<=8); /* otherwise an overflow is possible */
|
||||
FDK_ASSERT(len2<=8); /* otherwise an overflow is possible */
|
||||
/* init with some energy to prevent division by zero
|
||||
and to prevent splitting for very low levels */
|
||||
accu1_init = scaleValue((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY))),-energies_e);
|
||||
accu2_init = scaleValue((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY))),-energies_e);
|
||||
accu1_init = fMult(accu1_init, (FIXP_DBL)len1<<((DFRACT_BITS-1)-NRG_SHIFT-1))<<1;
|
||||
accu2_init = fMult(accu2_init, (FIXP_DBL)len2<<((DFRACT_BITS-1)-NRG_SHIFT-1))<<1;
|
||||
|
||||
for (j=0; j<nSfb; j++) {
|
||||
#define NRG_SCALE 3
|
||||
/* init with some energy to prevent division by zero
|
||||
and to prevent splitting for very low levels */
|
||||
accu1 = ((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY*8.0/32))) << fixMin(scaleEnergies[0],25))>>NRG_SCALE; /* complex init for compare with original version */
|
||||
accu2 = ((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY*8.0/32))) << fixMin(scaleEnergies[0],25))>>NRG_SCALE; /* can be simplified in dsp implementation */
|
||||
|
||||
accu1 = accu1_init;
|
||||
accu2 = accu2_init;
|
||||
accu_e = energies_e+3;
|
||||
|
||||
/* Sum up energies in first half */
|
||||
for (i=start; i<border; i++) {
|
||||
accu1 += (Energies[i][j]>>NRG_SCALE);
|
||||
accu1 += scaleValue(Energies[i][j], -energies_e_diff[i]);
|
||||
}
|
||||
|
||||
/* Sum up energies in second half */
|
||||
for (i=border; i<stop; i++) {
|
||||
accu2 += (Energies[i][j]>>NRG_SCALE);
|
||||
accu2 += scaleValue(Energies[i][j], -energies_e_diff[i]);
|
||||
}
|
||||
|
||||
/* Energy change in current band */
|
||||
tmp0 = CalcLdData(accu2);
|
||||
tmp1 = CalcLdData(accu1);
|
||||
tmp2 = (tmp0 - tmp1 + CalcLdData(len1)-CalcLdData(len2));
|
||||
delta = fixp_abs(fMult(tmp2, FL2FXCONST_DBL(0.6931471806f)));
|
||||
#define LN2 FL2FXCONST_DBL(0.6931471806f) /* ln(2) */
|
||||
tmp0 = fLog2(accu2, accu_e) - fLog2(accu1, accu_e);
|
||||
tmp1 = fLog2((FIXP_DBL)len1, 31) - fLog2((FIXP_DBL)len2, 31);
|
||||
delta = fMult(LN2, (tmp0 + tmp1));
|
||||
delta = (FIXP_DBL)FDKabs( delta );
|
||||
|
||||
/* Weighting with amplitude ratio of this band */
|
||||
result = (EnergyTotal == FL2FXCONST_DBL(0.0f))
|
||||
? FL2FXCONST_DBL(0.f)
|
||||
: FDKsbrEnc_LSI_divide_scale_fract( (accu1+accu2),
|
||||
(EnergyTotal>>NRG_SCALE)+(FIXP_DBL)1,
|
||||
(FIXP_DBL)MAXVAL_DBL >> fixMin(scaleEnergies[0],(DFRACT_BITS-1)) );
|
||||
accu_e++;
|
||||
accu1>>=1;
|
||||
accu2>>=1;
|
||||
if (accu_e & 1) {
|
||||
accu_e++;
|
||||
accu1>>=1;
|
||||
accu2>>=1;
|
||||
}
|
||||
|
||||
delta_sum += (FIXP_DBL)(fMult(sqrtFixp(result), delta));
|
||||
delta_sum += fMult(sqrtFixp(accu1+accu2), delta);
|
||||
*result_e = ((accu_e>>1) + LD_DATA_SHIFT);
|
||||
}
|
||||
|
||||
energyTotal_e+=1; /* for a defined square result exponent, the exponent has to be even */
|
||||
EnergyTotal<<=1;
|
||||
delta_sum = fMult(delta_sum, invSqrtNorm2(EnergyTotal, &tmp_e));
|
||||
*result_e = *result_e + (tmp_e-(energyTotal_e>>1));
|
||||
|
||||
return fMult(delta_sum, pos_weight);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -175,9 +231,12 @@ static FIXP_DBL spectralChange(FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FRE
|
||||
*******************************************************************************
|
||||
\brief Calculates total lowband energy
|
||||
|
||||
The return value nrgTotal is scaled by the factor (1/32.0)
|
||||
The input values Energies[0] (low-band) are scaled by the factor
|
||||
2^(14-*scaleEnergies[0])
|
||||
The input values Energies[1] (high-band) are scaled by the factor
|
||||
2^(14-*scaleEnergies[1])
|
||||
|
||||
\return total energy in the lowband
|
||||
\return total energy in the lowband, scaled by the factor 2^19
|
||||
*******************************************************************************/
|
||||
static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
|
||||
int *scaleEnergies,
|
||||
@ -194,6 +253,7 @@ static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
|
||||
int ts,k;
|
||||
|
||||
/* Sum up lowband energy from one frame at offset tran_off */
|
||||
/* freqBandTable[LORES] has MAX_FREQ_COEFFS/2 +1 coeefs max. */
|
||||
for (ts=tran_offdiv2; ts<YBufferWriteOffset; ts++) {
|
||||
for (k = 0; k < freqBandTable[0]; k++) {
|
||||
accu1 += Energies[ts][k] >> 6;
|
||||
@ -201,12 +261,12 @@ static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
|
||||
}
|
||||
for (; ts<tran_offdiv2+(slots>>nrgSzShift); ts++) {
|
||||
for (k = 0; k < freqBandTable[0]; k++) {
|
||||
accu2 += Energies[ts][k] >> 6;
|
||||
accu2 += Energies[ts][k] >> 9;
|
||||
}
|
||||
}
|
||||
|
||||
nrgTotal = ( (accu1 >> fixMin(scaleEnergies[0],(DFRACT_BITS-1)))
|
||||
+ (accu2 >> fixMin(scaleEnergies[1],(DFRACT_BITS-1))) ) << (2);
|
||||
nrgTotal = ( scaleValueSaturate(accu1, 1-scaleEnergies[0]) )
|
||||
+ ( scaleValueSaturate(accu2, 4-scaleEnergies[1]) );
|
||||
|
||||
return(nrgTotal);
|
||||
}
|
||||
@ -222,21 +282,23 @@ static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
|
||||
is 1 SBR-band. Therefore the data to be fed into the spectralChange
|
||||
function is reduced.
|
||||
|
||||
The values EnergiesM are scaled by the factor (1/32.0) and scaleEnergies[0]
|
||||
The return value nrgTotal is scaled by the factor (1/32.0)
|
||||
The values EnergiesM are scaled by the factor (2^19-scaleEnergies[0]) for
|
||||
slots<YBufferWriteOffset and by the factor (2^19-scaleEnergies[1]) for
|
||||
slots>=YBufferWriteOffset.
|
||||
|
||||
\return total energy in the highband
|
||||
\return total energy in the highband, scaled by factor 2^19
|
||||
*******************************************************************************/
|
||||
|
||||
static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */
|
||||
INT *scaleEnergies,
|
||||
INT YBufferWriteOffset,
|
||||
FIXP_DBL EnergiesM[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS], /*!< Combined output */
|
||||
UCHAR *RESTRICT freqBandTable,
|
||||
INT nSfb,
|
||||
INT sbrSlots,
|
||||
INT timeStep)
|
||||
{
|
||||
INT i,j,k,slotIn,slotOut,scale;
|
||||
INT i,j,k,slotIn,slotOut,scale[2];
|
||||
INT li,ui;
|
||||
FIXP_DBL nrgTotal;
|
||||
FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
|
||||
@ -245,7 +307,7 @@ static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */
|
||||
combine QMF-bands to SBR-bands,
|
||||
combine Left and Right channel */
|
||||
for (slotOut=0; slotOut<sbrSlots; slotOut++) {
|
||||
slotIn = 2*slotOut;
|
||||
slotIn = timeStep*slotOut;
|
||||
|
||||
for (j=0; j<nSfb; j++) {
|
||||
accu = FL2FXCONST_DBL(0.0f);
|
||||
@ -262,19 +324,29 @@ static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */
|
||||
}
|
||||
}
|
||||
|
||||
scale = fixMin(8,scaleEnergies[0]); /* scale energies down before add up */
|
||||
/* scale energies down before add up */
|
||||
scale[0] = fixMin(8,scaleEnergies[0]);
|
||||
scale[1] = fixMin(8,scaleEnergies[1]);
|
||||
|
||||
if ((scaleEnergies[0]-1) > (DFRACT_BITS-1) )
|
||||
if ((scaleEnergies[0]-scale[0]) > (DFRACT_BITS-1) || (scaleEnergies[1]-scale[0]) > (DFRACT_BITS-1))
|
||||
nrgTotal = FL2FXCONST_DBL(0.0f);
|
||||
else {
|
||||
/* Now add all energies */
|
||||
accu = FL2FXCONST_DBL(0.0f);
|
||||
for (slotOut=0; slotOut<sbrSlots; slotOut++) {
|
||||
|
||||
for (slotOut=0; slotOut<YBufferWriteOffset; slotOut++) {
|
||||
for (j=0; j<nSfb; j++) {
|
||||
accu += (EnergiesM[slotOut][j] >> scale);
|
||||
accu += (EnergiesM[slotOut][j] >> scale[0]);
|
||||
}
|
||||
}
|
||||
nrgTotal = accu >> (scaleEnergies[0]-scale);
|
||||
nrgTotal = accu >> (scaleEnergies[0]-scale[0]);
|
||||
|
||||
for (slotOut=YBufferWriteOffset; slotOut<sbrSlots; slotOut++) {
|
||||
for (j=0; j<nSfb; j++) {
|
||||
accu += (EnergiesM[slotOut][j] >> scale[0]);
|
||||
}
|
||||
}
|
||||
nrgTotal = accu >> (scaleEnergies[1]-scale[1]);
|
||||
}
|
||||
|
||||
return(nrgTotal);
|
||||
@ -299,18 +371,23 @@ FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
|
||||
int YBufferSzShift,
|
||||
int nSfb,
|
||||
int timeStep,
|
||||
int no_cols)
|
||||
int no_cols,
|
||||
FIXP_DBL* tonality)
|
||||
{
|
||||
if (tran_vector[1]==0) /* no transient was detected */
|
||||
{
|
||||
FIXP_DBL delta;
|
||||
FIXP_DBL EnergiesM[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS];
|
||||
INT delta_e;
|
||||
FIXP_DBL (*EnergiesM)[MAX_FREQ_COEFFS];
|
||||
FIXP_DBL EnergyTotal,newLowbandEnergy,newHighbandEnergy;
|
||||
INT border;
|
||||
INT sbrSlots = fMultI(GetInvInt(timeStep),no_cols);
|
||||
C_ALLOC_SCRATCH_START(_EnergiesM, FIXP_DBL, NUMBER_TIME_SLOTS_2304*MAX_FREQ_COEFFS)
|
||||
|
||||
FDK_ASSERT( sbrSlots * timeStep == no_cols );
|
||||
|
||||
EnergiesM = (FIXP_DBL(*)[MAX_FREQ_COEFFS])_EnergiesM;
|
||||
|
||||
/*
|
||||
Get Lowband-energy over a range of 2 frames (Look half a frame back and ahead).
|
||||
*/
|
||||
@ -324,16 +401,13 @@ FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
|
||||
|
||||
newHighbandEnergy = addHighbandEnergies(Energies,
|
||||
scaleEnergies,
|
||||
YBufferWriteOffset,
|
||||
EnergiesM,
|
||||
freqBandTable,
|
||||
nSfb,
|
||||
sbrSlots,
|
||||
timeStep);
|
||||
|
||||
if ( h_sbrTransientDetector->frameShift != 0 ) {
|
||||
if (tran_vector[1]==0)
|
||||
tran_vector[0] = 0;
|
||||
} else
|
||||
{
|
||||
/* prevLowBandEnergy: Corresponds to 1 frame, starting with half a frame look-behind
|
||||
newLowbandEnergy: Corresponds to 1 frame, starting in the middle of the current frame */
|
||||
@ -343,23 +417,39 @@ FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
|
||||
of a FIXFIX-frame with 2 envelopes. */
|
||||
border = (sbrSlots+1) >> 1;
|
||||
|
||||
if ( (INT)EnergyTotal&0xffffffe0 && (scaleEnergies[0]<32 || scaleEnergies[1]<32) ) /* i.e. > 31 */ {
|
||||
delta = spectralChange(EnergiesM,
|
||||
scaleEnergies,
|
||||
EnergyTotal,
|
||||
nSfb,
|
||||
0,
|
||||
border,
|
||||
sbrSlots);
|
||||
YBufferWriteOffset,
|
||||
sbrSlots,
|
||||
&delta_e
|
||||
);
|
||||
} else {
|
||||
delta = FL2FXCONST_DBL(0.0f);
|
||||
delta_e = 0;
|
||||
|
||||
if (delta > (h_sbrTransientDetector->split_thr >> LD_DATA_SHIFT)) /* delta scaled by 1/64 */
|
||||
/* set tonality to 0 when energy is very low, since the amplitude
|
||||
resolution should then be low as well */
|
||||
*tonality = FL2FXCONST_DBL(0.0f);
|
||||
}
|
||||
|
||||
|
||||
if ( fIsLessThan(h_sbrTransientDetector->split_thr_m, h_sbrTransientDetector->split_thr_e, delta, delta_e) ) {
|
||||
tran_vector[0] = 1; /* Set flag for splitting */
|
||||
else
|
||||
} else {
|
||||
tran_vector[0] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Update prevLowBandEnergy */
|
||||
h_sbrTransientDetector->prevLowBandEnergy = newLowbandEnergy;
|
||||
h_sbrTransientDetector->prevHighBandEnergy = newHighbandEnergy;
|
||||
C_ALLOC_SCRATCH_END(_EnergiesM, FIXP_DBL, NUMBER_TIME_SLOTS_2304*MAX_FREQ_COEFFS)
|
||||
}
|
||||
}
|
||||
|
||||
@ -636,6 +726,7 @@ FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTran,
|
||||
|
||||
int
|
||||
FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
|
||||
UINT sbrSyntaxFlags, /* SBR syntax flags derived from AOT. */
|
||||
INT frameSize,
|
||||
INT sampleFreq,
|
||||
sbrConfigurationPtr params,
|
||||
@ -649,8 +740,8 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
|
||||
{
|
||||
INT totalBitrate = params->codecSettings.standardBitrate * params->codecSettings.nChannels;
|
||||
INT codecBitrate = params->codecSettings.bitRate;
|
||||
FIXP_DBL bitrateFactor_fix, framedur_fix;
|
||||
INT scale_0, scale_1;
|
||||
FIXP_DBL bitrateFactor_m, framedur_fix;
|
||||
INT bitrateFactor_e, tmp_e;
|
||||
|
||||
FDKmemclear(h_sbrTransientDetector,sizeof(SBR_TRANSIENT_DETECTOR));
|
||||
|
||||
@ -658,11 +749,12 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
|
||||
h_sbrTransientDetector->tran_off = tran_off;
|
||||
|
||||
if(codecBitrate) {
|
||||
bitrateFactor_fix = fDivNorm((FIXP_DBL)totalBitrate, (FIXP_DBL)(codecBitrate<<2),&scale_0);
|
||||
bitrateFactor_m = fDivNorm((FIXP_DBL)totalBitrate, (FIXP_DBL)(codecBitrate<<2),&bitrateFactor_e);
|
||||
bitrateFactor_e += 2;
|
||||
}
|
||||
else {
|
||||
bitrateFactor_fix = FL2FXCONST_DBL(1.0/4.0);
|
||||
scale_0 = 0;
|
||||
bitrateFactor_m = FL2FXCONST_DBL(1.0/4.0);
|
||||
bitrateFactor_e = 2;
|
||||
}
|
||||
|
||||
framedur_fix = fDivNorm(frameSize, sampleFreq);
|
||||
@ -674,9 +766,13 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
|
||||
FIXP_DBL tmp = framedur_fix - FL2FXCONST_DBL(0.010);
|
||||
|
||||
tmp = fixMax(tmp, FL2FXCONST_DBL(0.0001));
|
||||
tmp = fDivNorm(FL2FXCONST_DBL(0.000075), fPow2(tmp), &scale_1);
|
||||
tmp = fDivNorm(FL2FXCONST_DBL(0.000075), fPow2(tmp), &tmp_e);
|
||||
|
||||
scale_1 = (scale_1 + scale_0 + 2);
|
||||
bitrateFactor_e = (tmp_e + bitrateFactor_e);
|
||||
|
||||
if(sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
|
||||
bitrateFactor_e--; /* divide by 2 */
|
||||
}
|
||||
|
||||
FDK_ASSERT(no_cols <= QMF_MAX_TIME_SLOTS);
|
||||
FDK_ASSERT(no_rows <= QMF_CHANNELS);
|
||||
@ -684,7 +780,8 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
|
||||
h_sbrTransientDetector->no_cols = no_cols;
|
||||
h_sbrTransientDetector->tran_thr = (FIXP_DBL)((params->tran_thr << (32-24-1)) / no_rows);
|
||||
h_sbrTransientDetector->tran_fc = tran_fc;
|
||||
h_sbrTransientDetector->split_thr = scaleValueSaturate(fMult(tmp, bitrateFactor_fix), scale_1);
|
||||
h_sbrTransientDetector->split_thr_m = fMult(tmp, bitrateFactor_m);
|
||||
h_sbrTransientDetector->split_thr_e = bitrateFactor_e;
|
||||
h_sbrTransientDetector->no_rows = no_rows;
|
||||
h_sbrTransientDetector->mode = params->tran_det_mode;
|
||||
h_sbrTransientDetector->prevLowBandEnergy = FL2FXCONST_DBL(0.0f);
|
||||
@ -692,3 +789,281 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
#define ENERGY_SCALING_SIZE 32
|
||||
|
||||
INT FDKsbrEnc_InitSbrFastTransientDetector(
|
||||
HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
|
||||
const INT time_slots_per_frame,
|
||||
const INT bandwidth_qmf_slot,
|
||||
const INT no_qmf_channels,
|
||||
const INT sbr_qmf_1st_band
|
||||
)
|
||||
{
|
||||
|
||||
int i, e;
|
||||
int buff_size;
|
||||
FIXP_DBL myExp;
|
||||
FIXP_DBL myExpSlot;
|
||||
|
||||
h_sbrFastTransientDetector->lookahead = TRAN_DET_LOOKAHEAD;
|
||||
h_sbrFastTransientDetector->nTimeSlots = time_slots_per_frame;
|
||||
|
||||
buff_size = h_sbrFastTransientDetector->nTimeSlots + h_sbrFastTransientDetector->lookahead;
|
||||
|
||||
for(i=0; i< buff_size; i++) {
|
||||
h_sbrFastTransientDetector->delta_energy[i] = FL2FXCONST_DBL(0.0f);
|
||||
h_sbrFastTransientDetector->energy_timeSlots[i] = FL2FXCONST_DBL(0.0f);
|
||||
h_sbrFastTransientDetector->lowpass_energy[i] = FL2FXCONST_DBL(0.0f);
|
||||
h_sbrFastTransientDetector->transientCandidates[i] = 0;
|
||||
}
|
||||
|
||||
FDK_ASSERT(bandwidth_qmf_slot > 0.f);
|
||||
h_sbrFastTransientDetector->stopBand = fMin(TRAN_DET_STOP_FREQ/bandwidth_qmf_slot, no_qmf_channels);
|
||||
h_sbrFastTransientDetector->startBand = fMin(sbr_qmf_1st_band, h_sbrFastTransientDetector->stopBand - TRAN_DET_MIN_QMFBANDS);
|
||||
|
||||
FDK_ASSERT(h_sbrFastTransientDetector->startBand < no_qmf_channels);
|
||||
FDK_ASSERT(h_sbrFastTransientDetector->startBand < h_sbrFastTransientDetector->stopBand);
|
||||
FDK_ASSERT(h_sbrFastTransientDetector->startBand > 1);
|
||||
FDK_ASSERT(h_sbrFastTransientDetector->stopBand > 1);
|
||||
|
||||
/* the energy weighting and adding up has a headroom of 6 Bits,
|
||||
so up to 64 bands can be added without potential overflow. */
|
||||
FDK_ASSERT(h_sbrFastTransientDetector->stopBand - h_sbrFastTransientDetector->startBand <= 64);
|
||||
|
||||
/* QMF_HP_dB_SLOPE_FIX says that we want a 20 dB per 16 kHz HP filter.
|
||||
The following lines map this to the QMF bandwidth. */
|
||||
#define EXP_E 7 /* QMF_CHANNELS (=64) multiplications max, max. allowed sum is 0.5 */
|
||||
myExp = fMultNorm(QMF_HP_dBd_SLOPE_FIX, (FIXP_DBL)bandwidth_qmf_slot, &e);
|
||||
myExp = scaleValueSaturate(myExp, e+0+DFRACT_BITS-1-EXP_E);
|
||||
myExpSlot = myExp;
|
||||
|
||||
for(i=0; i<QMF_CHANNELS; i++){
|
||||
/* Calculate dBf over all qmf bands:
|
||||
dBf = (10^(0.002266f/10*bw(slot)))^(band) =
|
||||
= 2^(log2(10)*0.002266f/10*bw(slot)*band) =
|
||||
= 2^(0.00075275f*bw(slot)*band) */
|
||||
|
||||
FIXP_DBL dBf_m; /* dBf mantissa */
|
||||
INT dBf_e; /* dBf exponent */
|
||||
INT tmp;
|
||||
|
||||
INT dBf_int; /* dBf integer part */
|
||||
FIXP_DBL dBf_fract; /* dBf fractional part */
|
||||
|
||||
/* myExp*(i+1) = myExp_int - myExp_fract
|
||||
myExp*(i+1) is split up here for better accuracy of CalcInvLdData(),
|
||||
for its result can be split up into an integer and a fractional part */
|
||||
|
||||
/* Round up to next integer */
|
||||
FIXP_DBL myExp_int = (myExpSlot & (FIXP_DBL)0xfe000000) + (FIXP_DBL)0x02000000;
|
||||
|
||||
/* This is the fractional part that needs to be substracted */
|
||||
FIXP_DBL myExp_fract = myExp_int - myExpSlot;
|
||||
|
||||
/* Calc integer part */
|
||||
dBf_int = CalcInvLdData(myExp_int);
|
||||
/* The result needs to be re-scaled. The ld(myExp_int) had been scaled by EXP_E,
|
||||
the CalcInvLdData expects the operand to be scaled by LD_DATA_SHIFT.
|
||||
Therefore, the correctly scaled result is dBf_int^(2^(EXP_E-LD_DATA_SHIFT)),
|
||||
which is dBf_int^2 */
|
||||
dBf_int *= dBf_int;
|
||||
|
||||
/* Calc fractional part */
|
||||
dBf_fract = CalcInvLdData(-myExp_fract);
|
||||
/* The result needs to be re-scaled. The ld(myExp_fract) had been scaled by EXP_E,
|
||||
the CalcInvLdData expects the operand to be scaled by LD_DATA_SHIFT.
|
||||
Therefore, the correctly scaled result is dBf_fract^(2^(EXP_E-LD_DATA_SHIFT)),
|
||||
which is dBf_fract^2 */
|
||||
dBf_fract = fMultNorm(dBf_fract, dBf_fract, &tmp);
|
||||
|
||||
/* Get worst case scaling of multiplication result */
|
||||
dBf_e = (DFRACT_BITS-1 - tmp) - CountLeadingBits(dBf_int);
|
||||
|
||||
/* Now multiply integer with fractional part of the result, thus resulting
|
||||
in the overall accurate fractional result */
|
||||
dBf_m = fMultNorm(dBf_int, dBf_fract, &e);
|
||||
dBf_m = scaleValueSaturate(dBf_m, e+DFRACT_BITS-1+tmp-dBf_e);
|
||||
myExpSlot += myExp;
|
||||
|
||||
/* Keep the results */
|
||||
h_sbrFastTransientDetector->dBf_m[i] = dBf_m;
|
||||
h_sbrFastTransientDetector->dBf_e[i] = dBf_e;
|
||||
|
||||
}
|
||||
|
||||
/* Make sure that dBf is greater than 1.0 (because it should be a highpass) */
|
||||
/* ... */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FDKsbrEnc_fastTransientDetect(
|
||||
const HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
|
||||
const FIXP_DBL *const *Energies,
|
||||
const int *const scaleEnergies,
|
||||
const INT YBufferWriteOffset,
|
||||
UCHAR *const tran_vector
|
||||
)
|
||||
{
|
||||
int timeSlot, band;
|
||||
|
||||
FIXP_DBL max_delta_energy; /* helper to store maximum energy ratio */
|
||||
int max_delta_energy_scale; /* helper to store scale of maximum energy ratio */
|
||||
int ind_max = 0; /* helper to store index of maximum energy ratio */
|
||||
int isTransientInFrame = 0;
|
||||
|
||||
const int nTimeSlots = h_sbrFastTransientDetector->nTimeSlots;
|
||||
const int lookahead = h_sbrFastTransientDetector->lookahead;
|
||||
const int startBand = h_sbrFastTransientDetector->startBand;
|
||||
const int stopBand = h_sbrFastTransientDetector->stopBand;
|
||||
|
||||
int * transientCandidates = h_sbrFastTransientDetector->transientCandidates;
|
||||
|
||||
FIXP_DBL * energy_timeSlots = h_sbrFastTransientDetector->energy_timeSlots;
|
||||
int * energy_timeSlots_scale = h_sbrFastTransientDetector->energy_timeSlots_scale;
|
||||
|
||||
FIXP_DBL * delta_energy = h_sbrFastTransientDetector->delta_energy;
|
||||
int * delta_energy_scale = h_sbrFastTransientDetector->delta_energy_scale;
|
||||
|
||||
const FIXP_DBL thr = TRAN_DET_THRSHLD;
|
||||
const INT thr_scale = TRAN_DET_THRSHLD_SCALE;
|
||||
|
||||
/*reset transient info*/
|
||||
tran_vector[2] = 0;
|
||||
|
||||
/* reset transient candidates */
|
||||
FDKmemclear(transientCandidates+lookahead, nTimeSlots*sizeof(int));
|
||||
|
||||
for(timeSlot = lookahead; timeSlot < nTimeSlots + lookahead; timeSlot++) {
|
||||
int i, norm;
|
||||
FIXP_DBL tmpE = FL2FXCONST_DBL(0.0f);
|
||||
int headroomEnSlot = DFRACT_BITS-1;
|
||||
|
||||
FIXP_DBL smallNRG = FL2FXCONST_DBL(1e-2f);
|
||||
FIXP_DBL denominator;
|
||||
INT denominator_scale;
|
||||
|
||||
/* determine minimum headroom of energy values for this timeslot */
|
||||
for(band = startBand; band < stopBand; band++) {
|
||||
int tmp_headroom = fNormz(Energies[timeSlot][band])-1;
|
||||
if(tmp_headroom < headroomEnSlot){
|
||||
headroomEnSlot = tmp_headroom;
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0, band = startBand; band < stopBand; band++, i++) {
|
||||
/* energy is weighted by weightingfactor stored in dBf_m array */
|
||||
/* dBf_m index runs from 0 to stopBand-startband */
|
||||
/* energy shifted by calculated headroom for maximum precision */
|
||||
FIXP_DBL weightedEnergy = fMult(Energies[timeSlot][band]<<headroomEnSlot, h_sbrFastTransientDetector->dBf_m[i]);
|
||||
|
||||
/* energy is added up */
|
||||
/* shift by 6 to have a headroom for maximum 64 additions */
|
||||
/* shift by dBf_e to handle weighting factor dependent scale factors */
|
||||
tmpE += weightedEnergy >> (6 + (10 - h_sbrFastTransientDetector->dBf_e[i]));
|
||||
}
|
||||
|
||||
/* store calculated energy for timeslot */
|
||||
energy_timeSlots[timeSlot] = tmpE;
|
||||
|
||||
/* calculate overall scale factor for energy of this timeslot */
|
||||
/* = original scale factor of energies (-scaleEnergies[0]+2*QMF_SCALE_OFFSET or -scaleEnergies[1]+2*QMF_SCALE_OFFSET */
|
||||
/* depending on YBufferWriteOffset) */
|
||||
/* + weighting factor scale (10) */
|
||||
/* + adding up scale factor ( 6) */
|
||||
/* - headroom of energy value (headroomEnSlot) */
|
||||
if(timeSlot < YBufferWriteOffset){
|
||||
energy_timeSlots_scale[timeSlot] = (-scaleEnergies[0]+2*QMF_SCALE_OFFSET) + (10+6) - headroomEnSlot;
|
||||
} else {
|
||||
energy_timeSlots_scale[timeSlot] = (-scaleEnergies[1]+2*QMF_SCALE_OFFSET) + (10+6) - headroomEnSlot;
|
||||
}
|
||||
|
||||
/* Add a small energy to the denominator, thus making the transient
|
||||
detection energy-dependent. Loud transients are being detected,
|
||||
silent ones not. */
|
||||
|
||||
/* make sure that smallNRG does not overflow */
|
||||
if ( -energy_timeSlots_scale[timeSlot-1] + 1 > 5 )
|
||||
{
|
||||
denominator = smallNRG;
|
||||
denominator_scale = 0;
|
||||
} else {
|
||||
/* Leave an additional headroom of 1 bit for this addition. */
|
||||
smallNRG = scaleValue(smallNRG, -(energy_timeSlots_scale[timeSlot-1] + 1));
|
||||
denominator = (energy_timeSlots[timeSlot-1]>>1) + smallNRG;
|
||||
denominator_scale = energy_timeSlots_scale[timeSlot-1]+1;
|
||||
}
|
||||
|
||||
delta_energy[timeSlot] = fDivNorm(energy_timeSlots[timeSlot], denominator, &norm);
|
||||
delta_energy_scale[timeSlot] = energy_timeSlots_scale[timeSlot] - denominator_scale + norm;
|
||||
}
|
||||
|
||||
/*get transient candidates*/
|
||||
/* For every timeslot, check if delta(E) exceeds the threshold. If it did,
|
||||
it could potentially be marked as a transient candidate. However, the 2
|
||||
slots before the current one must not be transients with an energy higher
|
||||
than 1.4*E(current). If both aren't transients or if the energy of the
|
||||
current timesolot is more than 1.4 times higher than the energy in the
|
||||
last or the one before the last slot, it is marked as a transient.*/
|
||||
|
||||
FDK_ASSERT(lookahead >= 2);
|
||||
for(timeSlot = lookahead; timeSlot < nTimeSlots + lookahead; timeSlot++) {
|
||||
FIXP_DBL energy_cur_slot_weighted = fMult(energy_timeSlots[timeSlot],FL2FXCONST_DBL(1.0f/1.4f));
|
||||
if( !fIsLessThan(delta_energy[timeSlot], delta_energy_scale[timeSlot], thr, thr_scale) &&
|
||||
( ((transientCandidates[timeSlot-2]==0) && (transientCandidates[timeSlot-1]==0)) ||
|
||||
!fIsLessThan(energy_cur_slot_weighted, energy_timeSlots_scale[timeSlot], energy_timeSlots[timeSlot-1], energy_timeSlots_scale[timeSlot-1] ) ||
|
||||
!fIsLessThan(energy_cur_slot_weighted, energy_timeSlots_scale[timeSlot], energy_timeSlots[timeSlot-2], energy_timeSlots_scale[timeSlot-2] )
|
||||
)
|
||||
)
|
||||
{
|
||||
/* in case of strong transients, subsequent
|
||||
* qmf slots might be recognized as transients. */
|
||||
transientCandidates[timeSlot] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*get transient with max energy*/
|
||||
max_delta_energy = FL2FXCONST_DBL(0.0f);
|
||||
max_delta_energy_scale = 0;
|
||||
ind_max = 0;
|
||||
isTransientInFrame = 0;
|
||||
for(timeSlot = 0; timeSlot < nTimeSlots; timeSlot++) {
|
||||
int scale = fMax(delta_energy_scale[timeSlot], max_delta_energy_scale);
|
||||
if(transientCandidates[timeSlot] && ( (delta_energy[timeSlot] >> (scale - delta_energy_scale[timeSlot])) > (max_delta_energy >> (scale - max_delta_energy_scale)) ) ) {
|
||||
max_delta_energy = delta_energy[timeSlot];
|
||||
max_delta_energy_scale = scale;
|
||||
ind_max = timeSlot;
|
||||
isTransientInFrame = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*from all transient candidates take the one with the biggest energy*/
|
||||
if(isTransientInFrame) {
|
||||
tran_vector[0] = ind_max;
|
||||
tran_vector[1] = 1;
|
||||
} else {
|
||||
/*reset transient info*/
|
||||
tran_vector[0] = tran_vector[1] = 0;
|
||||
}
|
||||
|
||||
/*check for transients in lookahead*/
|
||||
for(timeSlot = nTimeSlots; timeSlot < nTimeSlots + lookahead; timeSlot++) {
|
||||
if(transientCandidates[timeSlot]) {
|
||||
tran_vector[2] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*update buffers*/
|
||||
for(timeSlot = 0; timeSlot < lookahead; timeSlot++) {
|
||||
transientCandidates[timeSlot] = transientCandidates[nTimeSlots + timeSlot];
|
||||
|
||||
/* fixpoint stuff */
|
||||
energy_timeSlots[timeSlot] = energy_timeSlots[nTimeSlots + timeSlot];
|
||||
energy_timeSlots_scale[timeSlot] = energy_timeSlots_scale[nTimeSlots + timeSlot];
|
||||
|
||||
delta_energy[timeSlot] = delta_energy[nTimeSlots + timeSlot];
|
||||
delta_energy_scale[timeSlot] = delta_energy_scale[nTimeSlots + timeSlot];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* -----------------------------------------------------------------------------------------------------------
|
||||
Software License for The Fraunhofer FDK AAC Codec Library for Android
|
||||
|
||||
© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
|
||||
All rights reserved.
|
||||
|
||||
1. INTRODUCTION
|
||||
@ -96,7 +96,8 @@ typedef struct
|
||||
FIXP_DBL transients[QMF_MAX_TIME_SLOTS+(QMF_MAX_TIME_SLOTS/2)];
|
||||
FIXP_DBL thresholds[QMF_CHANNELS];
|
||||
FIXP_DBL tran_thr; /* Master threshold for transient signals */
|
||||
FIXP_DBL split_thr; /* Threshold for splitting FIXFIX-frames into 2 env */
|
||||
FIXP_DBL split_thr_m; /* Threshold for splitting FIXFIX-frames into 2 env */
|
||||
INT split_thr_e; /* Scale for splitting threshold */
|
||||
FIXP_DBL prevLowBandEnergy; /* Energy of low band */
|
||||
FIXP_DBL prevHighBandEnergy; /* Energy of high band */
|
||||
INT tran_fc; /* Number of lowband subbands to discard */
|
||||
@ -112,6 +113,57 @@ SBR_TRANSIENT_DETECTOR;
|
||||
|
||||
typedef SBR_TRANSIENT_DETECTOR *HANDLE_SBR_TRANSIENT_DETECTOR;
|
||||
|
||||
#define TRAN_DET_LOOKAHEAD 2
|
||||
#define TRAN_DET_START_FREQ 4500 /*start frequency for transient detection*/
|
||||
#define TRAN_DET_STOP_FREQ 13500 /*stop frequency for transient detection*/
|
||||
#define TRAN_DET_MIN_QMFBANDS 4 /* minimum qmf bands for transient detection */
|
||||
#define QMF_HP_dBd_SLOPE_FIX FL2FXCONST_DBL(0.00075275f) /* 0.002266f/10 * log2(10) */
|
||||
#define TRAN_DET_THRSHLD FL2FXCONST_DBL(3.2f/4.f)
|
||||
#define TRAN_DET_THRSHLD_SCALE (2)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT transientCandidates[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
|
||||
INT nTimeSlots;
|
||||
INT lookahead;
|
||||
INT startBand;
|
||||
INT stopBand;
|
||||
|
||||
FIXP_DBL dBf_m[QMF_CHANNELS];
|
||||
INT dBf_e[QMF_CHANNELS];
|
||||
|
||||
FIXP_DBL energy_timeSlots[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
|
||||
INT energy_timeSlots_scale[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
|
||||
|
||||
FIXP_DBL delta_energy[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
|
||||
INT delta_energy_scale[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
|
||||
|
||||
FIXP_DBL lowpass_energy[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
|
||||
INT lowpass_energy_scale[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
|
||||
#if defined (FTD_LOG)
|
||||
FDKFILE *ftd_log;
|
||||
#endif
|
||||
}
|
||||
FAST_TRAN_DETECTOR;
|
||||
typedef FAST_TRAN_DETECTOR *HANDLE_FAST_TRAN_DET;
|
||||
|
||||
|
||||
INT FDKsbrEnc_InitSbrFastTransientDetector(
|
||||
HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
|
||||
const INT time_slots_per_frame,
|
||||
const INT bandwidth_qmf_slot,
|
||||
const INT no_qmf_channels,
|
||||
const INT sbr_qmf_1st_band
|
||||
);
|
||||
|
||||
void FDKsbrEnc_fastTransientDetect(
|
||||
const HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
|
||||
const FIXP_DBL *const *Energies,
|
||||
const int *const scaleEnergies,
|
||||
const INT YBufferWriteOffset,
|
||||
UCHAR *const tran_vector
|
||||
);
|
||||
|
||||
void
|
||||
FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
|
||||
FIXP_DBL **Energies,
|
||||
@ -124,6 +176,7 @@ FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
|
||||
|
||||
int
|
||||
FDKsbrEnc_InitSbrTransientDetector (HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
|
||||
UINT sbrSyntaxFlags, /* SBR syntax flags derived from AOT. */
|
||||
INT frameSize,
|
||||
INT sampleFreq,
|
||||
sbrConfigurationPtr params,
|
||||
@ -145,6 +198,6 @@ FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
|
||||
int YBufferSzShift,
|
||||
int nSfb,
|
||||
int timeStep,
|
||||
int no_cols);
|
||||
|
||||
int no_cols,
|
||||
FIXP_DBL* tonality);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user