diff options
Diffstat (limited to 'libAACdec/src/aacdecoder_lib.cpp')
-rw-r--r-- | libAACdec/src/aacdecoder_lib.cpp | 146 |
1 files changed, 136 insertions, 10 deletions
diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index ec8f41e..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 5 +#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; } @@ -420,8 +422,8 @@ aacDecoder_SetParam ( const HANDLE_AACDECODER self, /*!< Handle of the decode self->outputInterleaved = value; break; - case AAC_PCM_OUTPUT_CHANNELS: - if (value < -1 || value > (6)) { + case AAC_PCM_MIN_OUTPUT_CHANNELS: + if (value < -1 || value > (8)) { return AAC_DEC_SET_PARAM_FAIL; } { @@ -429,7 +431,30 @@ aacDecoder_SetParam ( const HANDLE_AACDECODER self, /*!< Handle of the decode err = pcmDmx_SetParam ( hPcmDmx, - NUMBER_OF_OUTPUT_CHANNELS, + MIN_NUMBER_OF_OUTPUT_CHANNELS, + value ); + + switch (err) { + case PCMDMX_OK: + break; + case PCMDMX_INVALID_HANDLE: + return AAC_DEC_INVALID_HANDLE; + default: + return AAC_DEC_SET_PARAM_FAIL; + } + } + break; + + case AAC_PCM_MAX_OUTPUT_CHANNELS: + if (value < -1 || value > (8)) { + return AAC_DEC_SET_PARAM_FAIL; + } + { + PCMDMX_ERROR err; + + err = pcmDmx_SetParam ( + hPcmDmx, + MAX_NUMBER_OF_OUTPUT_CHANNELS, value ); switch (err) { @@ -449,7 +474,7 @@ aacDecoder_SetParam ( const HANDLE_AACDECODER self, /*!< Handle of the decode err = pcmDmx_SetParam ( hPcmDmx, - DUAL_CHANNEL_DOWNMIX_MODE, + DMX_DUAL_CHANNEL_MODE, value ); switch (err) { @@ -463,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: @@ -609,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 */ @@ -784,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), @@ -825,6 +910,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( if (self->sbrEnabled) { SBR_ERROR sbrError = SBRDEC_OK; + int chOutMapIdx = ((self->chMapIndex==0) && (self->streamInfo.numChannels<7)) ? self->streamInfo.numChannels : self->chMapIndex; /* set params */ sbrDecoder_SetParam ( self->hSbrDecoder, @@ -838,7 +924,16 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( (self->flags & AC_LD_MPS) ? 1 : 0 ); } + { + PCMDMX_ERROR dmxErr; + INT maxOutCh = 0; + dmxErr = pcmDmx_GetParam(self->hPcmUtils, MAX_NUMBER_OF_OUTPUT_CHANNELS, &maxOutCh); + if ( (dmxErr == PCMDMX_OK) && (maxOutCh == 1) ) { + /* Disable PS processing if we have to create a mono output signal. */ + self->psPossible = 0; + } + } /* apply SBR processing */ @@ -846,7 +941,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( pTimeData, &self->streamInfo.numChannels, &self->streamInfo.sampleRate, - self->channelOutputMapping[self->streamInfo.numChannels-1], + self->channelOutputMapping[chOutMapIdx], interleaved, self->frameOK, &self->psPossible); @@ -870,19 +965,20 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( self->channelType[1] = ACT_FRONT; self->channelIndices[0] = 0; self->channelIndices[1] = 1; - } else { - self->flags &= ~AC_PS_PRESENT; } } } + { + INT pcmLimiterScale = 0; + PCMDMX_ERROR dmxErr = PCMDMX_OK; if ( flags & (AACDEC_INTR | AACDEC_CLRHIST) ) { /* delete data from the past (e.g. mixdown coeficients) */ pcmDmx_Reset( self->hPcmUtils, PCMDMX_RESET_BS_DATA ); } /* do PCM post processing */ - pcmDmx_ApplyFrame ( + dmxErr = pcmDmx_ApplyFrame ( self->hPcmUtils, pTimeData, self->streamInfo.frameSize, @@ -890,9 +986,36 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( interleaved, self->channelType, self->channelIndices, - self->channelOutputMapping + self->channelOutputMapping, + (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 + ); + } + } /* Signal interruption to take effect in next frame. */ @@ -917,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 ); |