diff options
author | Jean-Michel Trivi <jmtrivi@google.com> | 2013-12-30 16:01:08 -0800 |
---|---|---|
committer | Jean-Michel Trivi <jmtrivi@google.com> | 2014-03-31 23:41:44 +0000 |
commit | 603f48ab99ce76f552f4f6f85d06b8c5b94c698e (patch) | |
tree | 303937f6779cdb798e3cec67ebe32abb39eab15b /libAACdec/src/aacdecoder_lib.cpp | |
parent | 629f60c0e71f4a5ad273d5ab3fc6964e5eb1f9f4 (diff) | |
download | fdk-aac-603f48ab99ce76f552f4f6f85d06b8c5b94c698e.tar.gz fdk-aac-603f48ab99ce76f552f4f6f85d06b8c5b94c698e.tar.bz2 fdk-aac-603f48ab99ce76f552f4f6f85d06b8c5b94c698e.zip |
AAC Decoder: introduce time domain limiter
Introduce time domain limiter. The module is per default enabled for all
AAC-LC and HE-AAC v1/2 streams. For all ER-AAC-LD and ER-AAC-ELD streams
the limiter is disabled per default. The feature can be en- or disabled
via dynamic API parameter. Note that the limiter introduces an additional
output delay which depends on the module parameters and the streams
sampling rate.
Bug 9428126
Change-Id: I299a072340b33e2c324facbd347a72c8de3d380e
Diffstat (limited to 'libAACdec/src/aacdecoder_lib.cpp')
-rw-r--r-- | libAACdec/src/aacdecoder_lib.cpp | 91 |
1 files changed, 89 insertions, 2 deletions
diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index d1b895d..98ef0de 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de /* Decoder library info */ #define AACDECODER_LIB_VL0 2 #define AACDECODER_LIB_VL1 5 -#define AACDECODER_LIB_VL2 6 +#define AACDECODER_LIB_VL2 7 #define AACDECODER_LIB_TITLE "AAC Decoder Lib" #define AACDECODER_LIB_BUILD_DATE __DATE__ #define AACDECODER_LIB_BUILD_TIME __TIME__ @@ -397,12 +397,14 @@ aacDecoder_SetParam ( const HANDLE_AACDECODER self, /*!< Handle of the decode CConcealParams *pConcealData = NULL; HANDLE_AAC_DRC hDrcInfo = NULL; HANDLE_PCM_DOWNMIX hPcmDmx = NULL; + TDLimiterPtr hPcmTdl = NULL; /* check decoder handle */ if (self != NULL) { pConcealData = &self->concealCommonData; hDrcInfo = self->hDrcInfo; hPcmDmx = self->hPcmUtils; + hPcmTdl = self->hLimiter; } else { errorStatus = AAC_DEC_INVALID_HANDLE; } @@ -486,6 +488,47 @@ aacDecoder_SetParam ( const HANDLE_AACDECODER self, /*!< Handle of the decode } break; + + case AAC_PCM_LIMITER_ENABLE: + if (value < -1 || value > 1) { + return AAC_DEC_SET_PARAM_FAIL; + } + if (self == NULL) { + return AAC_DEC_INVALID_HANDLE; + } + self->limiterEnableUser = value; + break; + + case AAC_PCM_LIMITER_ATTACK_TIME: + if (value <= 0) { /* module function converts value to unsigned */ + return AAC_DEC_SET_PARAM_FAIL; + } + switch (setLimiterAttack(hPcmTdl, value)) { + case TDLIMIT_OK: + break; + case TDLIMIT_INVALID_HANDLE: + return AAC_DEC_INVALID_HANDLE; + case TDLIMIT_INVALID_PARAMETER: + default: + return AAC_DEC_SET_PARAM_FAIL; + } + break; + + case AAC_PCM_LIMITER_RELEAS_TIME: + if (value <= 0) { /* module function converts value to unsigned */ + return AAC_DEC_SET_PARAM_FAIL; + } + switch (setLimiterRelease(hPcmTdl, value)) { + case TDLIMIT_OK: + break; + case TDLIMIT_INVALID_HANDLE: + return AAC_DEC_INVALID_HANDLE; + case TDLIMIT_INVALID_PARAMETER: + default: + return AAC_DEC_SET_PARAM_FAIL; + } + break; + case AAC_PCM_OUTPUT_CHANNEL_MAPPING: switch (value) { case 0: @@ -632,6 +675,14 @@ LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt, UINT goto bail; } + aacDec->hLimiter = createLimiter(TDL_ATTACK_DEFAULT_MS, TDL_RELEASE_DEFAULT_MS, SAMPLE_MAX, (8), 96000); + if (NULL == aacDec->hLimiter) { + err = -1; + goto bail; + } + aacDec->limiterEnableUser = (UCHAR)-1; + aacDec->limiterEnableCurr = 0; + /* Assure that all modules have same delay */ @@ -807,6 +858,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( self->streamInfo.numTotalBytes = 0; } + if (self->limiterEnableUser==(UCHAR)-1) { + /* Enbale limiter for all non-lowdelay AOT's. */ + self->limiterEnableCurr = ( self->flags & (AC_LD|AC_ELD) ) ? 0 : 1; + } + else { + /* Use limiter configuration as requested. */ + self->limiterEnableCurr = self->limiterEnableUser; + } + /* reset limiter gain on a per frame basis */ + self->extGain[0] = FL2FXCONST_DBL(1.0f/(float)(1<<TDL_GAIN_SCALING)); + ErrorStatus = CAacDecoder_DecodeFrame(self, flags | (fTpConceal ? AACDEC_CONCEAL : 0), @@ -909,6 +971,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( { + INT pcmLimiterScale = 0; PCMDMX_ERROR dmxErr = PCMDMX_OK; if ( flags & (AACDEC_INTR | AACDEC_CLRHIST) ) { /* delete data from the past (e.g. mixdown coeficients) */ @@ -924,13 +987,34 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( self->channelType, self->channelIndices, self->channelOutputMapping, - NULL + (self->limiterEnableCurr) ? &pcmLimiterScale : NULL ); if (dmxErr == PCMDMX_INVALID_MODE) { /* Announce the framework that the current combination of channel configuration and downmix * settings are not know to produce a predictable behavior and thus maybe produce strange output. */ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; } + + if ( flags & AACDEC_CLRHIST ) { + /* Delete the delayed signal. */ + resetLimiter(self->hLimiter); + } + if (self->limiterEnableCurr) + { + /* Set actual signal parameters */ + setLimiterNChannels(self->hLimiter, self->streamInfo.numChannels); + setLimiterSampleRate(self->hLimiter, self->streamInfo.sampleRate); + + applyLimiter( + self->hLimiter, + pTimeData, + self->extGain, + &pcmLimiterScale, + 1, + self->extGainDelay, + self->streamInfo.frameSize + ); + } } @@ -956,6 +1040,9 @@ LINKSPEC_CPP void aacDecoder_Close ( HANDLE_AACDECODER self ) return; + if (self->hLimiter != NULL) { + destroyLimiter(self->hLimiter); + } if (self->hPcmUtils != NULL) { pcmDmx_Close( &self->hPcmUtils ); |