Commit 603f48ab authored by Jean-Michel Trivi's avatar Jean-Michel Trivi

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
parent 629f60c0
This diff is collapsed.
...@@ -436,6 +436,16 @@ typedef enum ...@@ -436,6 +436,16 @@ typedef enum
2: Create a dual mono output signal from channel 2. \n 2: Create a dual mono output signal from channel 2. \n
3: Create a dual mono output signal by mixing both channels (L' = R' = 0.5*Ch1 + 0.5*Ch2). */ 3: Create a dual mono output signal by mixing both channels (L' = R' = 0.5*Ch1 + 0.5*Ch2). */
AAC_PCM_OUTPUT_CHANNEL_MAPPING = 0x0003, /*!< Output buffer channel ordering. 0: MPEG PCE style order, 1: WAV file channel order (default). */ AAC_PCM_OUTPUT_CHANNEL_MAPPING = 0x0003, /*!< Output buffer channel ordering. 0: MPEG PCE style order, 1: WAV file channel order (default). */
AAC_PCM_LIMITER_ENABLE = 0x0004, /*!< Enable signal level limiting. \n
-1: Auto-config. Enable limiter for all non-lowdelay configurations by default. \n
0: Disable limiter in general. \n
1: Enable limiter always.
It is recommended to call the decoder with a AACDEC_CLRHIST flag to reset all states when
the limiter switch is changed explicitly. */
AAC_PCM_LIMITER_ATTACK_TIME = 0x0005, /*!< Signal level limiting attack time in ms.
Default confguration is 15 ms. Adjustable range from 1 ms to 15 ms. */
AAC_PCM_LIMITER_RELEAS_TIME = 0x0006, /*!< Signal level limiting release time in ms.
Default configuration is 50 ms. Adjustable time must be larger than 0 ms. */
AAC_PCM_MIN_OUTPUT_CHANNELS = 0x0011, /*!< Minimum number of PCM output channels. If higher than the number of encoded audio channels, AAC_PCM_MIN_OUTPUT_CHANNELS = 0x0011, /*!< Minimum number of PCM output channels. If higher than the number of encoded audio channels,
a simple channel extension is applied. \n a simple channel extension is applied. \n
-1, 0: Disable channel extenstion feature. The decoder output contains the same number of -1, 0: Disable channel extenstion feature. The decoder output contains the same number of
......
...@@ -130,7 +130,6 @@ void aacDecoder_drcInit ( ...@@ -130,7 +130,6 @@ void aacDecoder_drcInit (
/* init control fields */ /* init control fields */
self->enable = 0; self->enable = 0;
self->numThreads = 0; self->numThreads = 0;
self->digitalNorm = 0;
/* init params */ /* init params */
pParams = &self->params; pParams = &self->params;
...@@ -139,8 +138,9 @@ void aacDecoder_drcInit ( ...@@ -139,8 +138,9 @@ void aacDecoder_drcInit (
pParams->usrCut = FL2FXCONST_DBL(0.0f); pParams->usrCut = FL2FXCONST_DBL(0.0f);
pParams->boost = FL2FXCONST_DBL(0.0f); pParams->boost = FL2FXCONST_DBL(0.0f);
pParams->usrBoost = FL2FXCONST_DBL(0.0f); pParams->usrBoost = FL2FXCONST_DBL(0.0f);
pParams->targetRefLevel = AACDEC_DRC_DEFAULT_REF_LEVEL; pParams->targetRefLevel = -1;
pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES; pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES;
pParams->applyDigitalNorm = 0;
pParams->applyHeavyCompression = 0; pParams->applyHeavyCompression = 0;
/* initial program ref level = target ref level */ /* initial program ref level = target ref level */
...@@ -222,11 +222,12 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( ...@@ -222,11 +222,12 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
return AAC_DEC_INVALID_HANDLE; return AAC_DEC_INVALID_HANDLE;
} }
if (value < 0) { if (value < 0) {
self->digitalNorm = 0; self->params.applyDigitalNorm = 0;
self->params.targetRefLevel = -1;
} }
else { else {
/* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */ /* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */
self->digitalNorm = 1; self->params.applyDigitalNorm = 1;
if (self->params.targetRefLevel != (SCHAR)value) { if (self->params.targetRefLevel != (SCHAR)value) {
self->params.targetRefLevel = (SCHAR)value; self->params.targetRefLevel = (SCHAR)value;
self->progRefLevel = (SCHAR)value; /* Always set the program reference level equal to the self->progRefLevel = (SCHAR)value; /* Always set the program reference level equal to the
...@@ -234,6 +235,16 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( ...@@ -234,6 +235,16 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
} }
} }
break; break;
case APPLY_NORMALIZATION:
if (value < 0 || value > 1) {
return AAC_DEC_SET_PARAM_FAIL;
}
if (self == NULL) {
return AAC_DEC_INVALID_HANDLE;
}
/* Store new parameter value */
self->params.applyDigitalNorm = (UCHAR)value;
break;
case APPLY_HEAVY_COMPRESSION: case APPLY_HEAVY_COMPRESSION:
if (value < 0 || value > 1) { if (value < 0 || value > 1) {
return AAC_DEC_SET_PARAM_FAIL; return AAC_DEC_SET_PARAM_FAIL;
...@@ -278,7 +289,7 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( ...@@ -278,7 +289,7 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
self->enable = ( (self->params.boost > (FIXP_DBL)0) self->enable = ( (self->params.boost > (FIXP_DBL)0)
|| (self->params.cut > (FIXP_DBL)0) || (self->params.cut > (FIXP_DBL)0)
|| (self->params.applyHeavyCompression != 0) || (self->params.applyHeavyCompression != 0)
|| (self->digitalNorm == 1) ); || (self->params.targetRefLevel >= 0) );
return ErrorStatus; return ErrorStatus;
...@@ -827,6 +838,7 @@ void aacDecoder_drcApply ( ...@@ -827,6 +838,7 @@ void aacDecoder_drcApply (
void *pSbrDec, void *pSbrDec,
CAacDecoderChannelInfo *pAacDecoderChannelInfo, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
CDrcChannelData *pDrcChData, CDrcChannelData *pDrcChData,
FIXP_DBL *extGain,
int ch, /* needed only for SBR */ int ch, /* needed only for SBR */
int aacFrameSize, int aacFrameSize,
int bSbrPresent ) int bSbrPresent )
...@@ -838,8 +850,8 @@ void aacDecoder_drcApply ( ...@@ -838,8 +850,8 @@ void aacDecoder_drcApply (
FIXP_DBL max_mantissa; FIXP_DBL max_mantissa;
INT max_exponent; INT max_exponent;
FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.0f); FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.5f);
INT norm_exponent = 0; INT norm_exponent = 1;
FIXP_DBL fact_mantissa[MAX_DRC_BANDS]; FIXP_DBL fact_mantissa[MAX_DRC_BANDS];
INT fact_exponent[MAX_DRC_BANDS]; INT fact_exponent[MAX_DRC_BANDS];
...@@ -861,6 +873,15 @@ void aacDecoder_drcApply ( ...@@ -861,6 +873,15 @@ void aacDecoder_drcApply (
if (!self->enable) { if (!self->enable) {
sbrDecoder_drcDisable( (HANDLE_SBRDECODER)pSbrDec, ch ); sbrDecoder_drcDisable( (HANDLE_SBRDECODER)pSbrDec, ch );
if (extGain != NULL) {
INT gainScale = (INT)*extGain;
/* The gain scaling must be passed to the function in the buffer pointed on by extGain. */
if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
*extGain = scaleValue(norm_mantissa, norm_exponent-gainScale);
} else {
FDK_ASSERT(0);
}
}
return; return;
} }
...@@ -876,7 +897,7 @@ void aacDecoder_drcApply ( ...@@ -876,7 +897,7 @@ void aacDecoder_drcApply (
reduced DAC SNR (if signal is attenuated) or clipping (if signal is reduced DAC SNR (if signal is attenuated) or clipping (if signal is
boosted) */ boosted) */
if (self->digitalNorm == 1) if (pParams->targetRefLevel >= 0)
{ {
/* 0.5^((targetRefLevel - progRefLevel)/24) */ /* 0.5^((targetRefLevel - progRefLevel)/24) */
norm_mantissa = fLdPow( norm_mantissa = fLdPow(
...@@ -886,7 +907,18 @@ void aacDecoder_drcApply ( ...@@ -886,7 +907,18 @@ void aacDecoder_drcApply (
3, 3,
&norm_exponent ); &norm_exponent );
} }
else { /* Always export the normalization gain (if possible). */
if (extGain != NULL) {
INT gainScale = (INT)*extGain;
/* The gain scaling must be passed to the function in the buffer pointed on by extGain. */
if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
*extGain = scaleValue(norm_mantissa, norm_exponent-gainScale);
} else {
FDK_ASSERT(0);
}
}
if (self->params.applyDigitalNorm == 0) {
/* Reset normalization gain since this module must not apply it */
norm_mantissa = FL2FXCONST_DBL(0.5f); norm_mantissa = FL2FXCONST_DBL(0.5f);
norm_exponent = 1; norm_exponent = 1;
} }
......
...@@ -98,7 +98,6 @@ amm-info@iis.fraunhofer.de ...@@ -98,7 +98,6 @@ amm-info@iis.fraunhofer.de
#include "channel.h" #include "channel.h"
#include "FDK_bitstream.h" #include "FDK_bitstream.h"
#define AACDEC_DRC_DEFAULT_REF_LEVEL ( 108 ) /* -27 dB below full scale (typical for movies) */
#define AACDEC_DRC_DFLT_EXPIRY_FRAMES ( 50 ) /* Default DRC data expiry time in AAC frames */ #define AACDEC_DRC_DFLT_EXPIRY_FRAMES ( 50 ) /* Default DRC data expiry time in AAC frames */
/** /**
...@@ -111,6 +110,7 @@ typedef enum ...@@ -111,6 +110,7 @@ typedef enum
TARGET_REF_LEVEL, TARGET_REF_LEVEL,
DRC_BS_DELAY, DRC_BS_DELAY,
DRC_DATA_EXPIRY_FRAME, DRC_DATA_EXPIRY_FRAME,
APPLY_NORMALIZATION,
APPLY_HEAVY_COMPRESSION APPLY_HEAVY_COMPRESSION
} AACDEC_DRC_PARAM; } AACDEC_DRC_PARAM;
...@@ -149,6 +149,8 @@ int aacDecoder_drcProlog ( ...@@ -149,6 +149,8 @@ int aacDecoder_drcProlog (
* \param pSbrDec pointer to SBR decoder instance * \param pSbrDec pointer to SBR decoder instance
* \param pAacDecoderChannelInfo AAC decoder channel instance to be processed * \param pAacDecoderChannelInfo AAC decoder channel instance to be processed
* \param pDrcDat DRC channel data * \param pDrcDat DRC channel data
* \param extGain Pointer to a FIXP_DBL where a externally applyable gain will be stored into (independently on whether it will be apply internally or not).
* At function call the buffer must hold the scale (0 >= scale < DFRACT_BITS) to be applied on the gain value.
* \param ch channel index * \param ch channel index
* \param aacFrameSize AAC frame size * \param aacFrameSize AAC frame size
* \param bSbrPresent flag indicating that SBR is present, in which case DRC is handed over to the SBR instance pSbrDec * \param bSbrPresent flag indicating that SBR is present, in which case DRC is handed over to the SBR instance pSbrDec
...@@ -158,6 +160,7 @@ void aacDecoder_drcApply ( ...@@ -158,6 +160,7 @@ void aacDecoder_drcApply (
void *pSbrDec, void *pSbrDec,
CAacDecoderChannelInfo *pAacDecoderChannelInfo, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
CDrcChannelData *pDrcDat, CDrcChannelData *pDrcDat,
FIXP_DBL *extGain,
int ch, int ch,
int aacFrameSize, int aacFrameSize,
int bSbrPresent ); int bSbrPresent );
......
...@@ -140,6 +140,7 @@ typedef struct ...@@ -140,6 +140,7 @@ typedef struct
UINT expiryFrame; UINT expiryFrame;
SCHAR targetRefLevel; SCHAR targetRefLevel;
UCHAR bsDelayEnable; UCHAR bsDelayEnable;
UCHAR applyDigitalNorm;
UCHAR applyHeavyCompression; UCHAR applyHeavyCompression;
} CDrcParams; } CDrcParams;
......
...@@ -1653,6 +1653,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( ...@@ -1653,6 +1653,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
{ {
int stride, offset, c; int stride, offset, c;
/* Turn on/off DRC modules level normalization in digital domain depending on the limiter status. */
aacDecoder_drcSetParam( self->hDrcInfo, APPLY_NORMALIZATION, (self->limiterEnableCurr) ? 0 : 1 );
/* Extract DRC control data and map it to channels (without bitstream delay) */ /* Extract DRC control data and map it to channels (without bitstream delay) */
aacDecoder_drcProlog ( aacDecoder_drcProlog (
self->hDrcInfo, self->hDrcInfo,
...@@ -1703,12 +1705,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( ...@@ -1703,12 +1705,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
/* Reset DRC control data for this channel */ /* Reset DRC control data for this channel */
aacDecoder_drcInitChannelData ( &self->pAacDecoderStaticChannelInfo[c]->drcData ); aacDecoder_drcInitChannelData ( &self->pAacDecoderStaticChannelInfo[c]->drcData );
} }
/* The DRC module demands to be called with the gain field holding the gain scale. */
self->extGain[0] = (FIXP_DBL)TDL_GAIN_SCALING;
/* DRC processing */ /* DRC processing */
aacDecoder_drcApply ( aacDecoder_drcApply (
self->hDrcInfo, self->hDrcInfo,
self->hSbrDecoder, self->hSbrDecoder,
pAacDecoderChannelInfo, pAacDecoderChannelInfo,
&self->pAacDecoderStaticChannelInfo[c]->drcData, &self->pAacDecoderStaticChannelInfo[c]->drcData,
self->extGain,
c, c,
self->streamInfo.aacSamplesPerFrame, self->streamInfo.aacSamplesPerFrame,
self->sbrEnabled self->sbrEnabled
...@@ -1726,6 +1731,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( ...@@ -1726,6 +1731,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
(self->frameOK && !(flags&AACDEC_CONCEAL)), (self->frameOK && !(flags&AACDEC_CONCEAL)),
self->aacCommonData.workBufferCore1->mdctOutTemp self->aacCommonData.workBufferCore1->mdctOutTemp
); );
self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
break; break;
case AACDEC_RENDER_ELDFB: case AACDEC_RENDER_ELDFB:
CBlock_FrequencyToTimeLowDelay( CBlock_FrequencyToTimeLowDelay(
...@@ -1735,6 +1741,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( ...@@ -1735,6 +1741,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
self->streamInfo.aacSamplesPerFrame, self->streamInfo.aacSamplesPerFrame,
stride stride
); );
self->extGainDelay = (self->streamInfo.aacSamplesPerFrame*2 - self->streamInfo.aacSamplesPerFrame/2 - 1)/2;
break; break;
default: default:
ErrorStatus = AAC_DEC_UNKNOWN; ErrorStatus = AAC_DEC_UNKNOWN;
......
...@@ -111,6 +111,7 @@ amm-info@iis.fraunhofer.de ...@@ -111,6 +111,7 @@ amm-info@iis.fraunhofer.de
#include "aacdec_drc.h" #include "aacdec_drc.h"
#include "pcmutils_lib.h" #include "pcmutils_lib.h"
#include "limiter.h"
/* Capabilities flags */ /* Capabilities flags */
...@@ -215,6 +216,12 @@ struct AAC_DECODER_INSTANCE { ...@@ -215,6 +216,12 @@ struct AAC_DECODER_INSTANCE {
CAncData ancData; /*!< structure to handle ancillary data */ CAncData ancData; /*!< structure to handle ancillary data */
HANDLE_PCM_DOWNMIX hPcmUtils; /*!< privat data for the PCM utils. */ HANDLE_PCM_DOWNMIX hPcmUtils; /*!< privat data for the PCM utils. */
TDLimiterPtr hLimiter; /*!< Handle of time domain limiter. */
UCHAR limiterEnableUser; /*!< The limiter configuration requested by the library user */
UCHAR limiterEnableCurr; /*!< The current limiter configuration. */
FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */
UINT extGainDelay; /*!< Delay that must be accounted for extGain. */
}; };
......
...@@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de ...@@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de
/* Decoder library info */ /* Decoder library info */
#define AACDECODER_LIB_VL0 2 #define AACDECODER_LIB_VL0 2
#define AACDECODER_LIB_VL1 5 #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_TITLE "AAC Decoder Lib"
#define AACDECODER_LIB_BUILD_DATE __DATE__ #define AACDECODER_LIB_BUILD_DATE __DATE__
#define AACDECODER_LIB_BUILD_TIME __TIME__ #define AACDECODER_LIB_BUILD_TIME __TIME__
...@@ -397,12 +397,14 @@ aacDecoder_SetParam ( const HANDLE_AACDECODER self, /*!< Handle of the decode ...@@ -397,12 +397,14 @@ aacDecoder_SetParam ( const HANDLE_AACDECODER self, /*!< Handle of the decode
CConcealParams *pConcealData = NULL; CConcealParams *pConcealData = NULL;
HANDLE_AAC_DRC hDrcInfo = NULL; HANDLE_AAC_DRC hDrcInfo = NULL;
HANDLE_PCM_DOWNMIX hPcmDmx = NULL; HANDLE_PCM_DOWNMIX hPcmDmx = NULL;
TDLimiterPtr hPcmTdl = NULL;
/* check decoder handle */ /* check decoder handle */
if (self != NULL) { if (self != NULL) {
pConcealData = &self->concealCommonData; pConcealData = &self->concealCommonData;
hDrcInfo = self->hDrcInfo; hDrcInfo = self->hDrcInfo;
hPcmDmx = self->hPcmUtils; hPcmDmx = self->hPcmUtils;
hPcmTdl = self->hLimiter;
} else { } else {
errorStatus = AAC_DEC_INVALID_HANDLE; errorStatus = AAC_DEC_INVALID_HANDLE;
} }
...@@ -486,6 +488,47 @@ aacDecoder_SetParam ( const HANDLE_AACDECODER self, /*!< Handle of the decode ...@@ -486,6 +488,47 @@ aacDecoder_SetParam ( const HANDLE_AACDECODER self, /*!< Handle of the decode
} }
break; 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: case AAC_PCM_OUTPUT_CHANNEL_MAPPING:
switch (value) { switch (value) {
case 0: case 0:
...@@ -632,6 +675,14 @@ LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt, UINT ...@@ -632,6 +675,14 @@ LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt, UINT
goto bail; 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 */ /* Assure that all modules have same delay */
...@@ -807,6 +858,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( ...@@ -807,6 +858,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
self->streamInfo.numTotalBytes = 0; 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, ErrorStatus = CAacDecoder_DecodeFrame(self,
flags | (fTpConceal ? AACDEC_CONCEAL : 0), flags | (fTpConceal ? AACDEC_CONCEAL : 0),
...@@ -909,6 +971,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( ...@@ -909,6 +971,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
{ {
INT pcmLimiterScale = 0;
PCMDMX_ERROR dmxErr = PCMDMX_OK; PCMDMX_ERROR dmxErr = PCMDMX_OK;
if ( flags & (AACDEC_INTR | AACDEC_CLRHIST) ) { if ( flags & (AACDEC_INTR | AACDEC_CLRHIST) ) {
/* delete data from the past (e.g. mixdown coeficients) */ /* delete data from the past (e.g. mixdown coeficients) */
...@@ -924,13 +987,34 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( ...@@ -924,13 +987,34 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
self->channelType, self->channelType,
self->channelIndices, self->channelIndices,
self->channelOutputMapping, self->channelOutputMapping,
NULL (self->limiterEnableCurr) ? &pcmLimiterScale : NULL
); );
if (dmxErr == PCMDMX_INVALID_MODE) { if (dmxErr == PCMDMX_INVALID_MODE) {
/* Announce the framework that the current combination of channel configuration and downmix /* 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. */ * settings are not know to produce a predictable behavior and thus maybe produce strange output. */
ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; 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 ) ...@@ -956,6 +1040,9 @@ LINKSPEC_CPP void aacDecoder_Close ( HANDLE_AACDECODER self )
return; return;
if (self->hLimiter != NULL) {
destroyLimiter(self->hLimiter);
}
if (self->hPcmUtils != NULL) { if (self->hPcmUtils != NULL) {
pcmDmx_Close( &self->hPcmUtils ); pcmDmx_Close( &self->hPcmUtils );
......
This diff is collapsed.
This diff is collapsed.
...@@ -148,7 +148,7 @@ amm-info@iis.fraunhofer.de ...@@ -148,7 +148,7 @@ amm-info@iis.fraunhofer.de
/* Decoder library info */ /* Decoder library info */
#define PCMDMX_LIB_VL0 2 #define PCMDMX_LIB_VL0 2
#define PCMDMX_LIB_VL1 4 #define PCMDMX_LIB_VL1 4
#define PCMDMX_LIB_VL2 1 #define PCMDMX_LIB_VL2 2
#define PCMDMX_LIB_TITLE "PCM Downmix Lib" #define PCMDMX_LIB_TITLE "PCM Downmix Lib"
#define PCMDMX_LIB_BUILD_DATE __DATE__ #define PCMDMX_LIB_BUILD_DATE __DATE__
#define PCMDMX_LIB_BUILD_TIME __TIME__ #define PCMDMX_LIB_BUILD_TIME __TIME__
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment