summaryrefslogtreecommitdiffstats
path: root/libAACdec/src/aacdec_drc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libAACdec/src/aacdec_drc.cpp')
-rw-r--r--libAACdec/src/aacdec_drc.cpp104
1 files changed, 89 insertions, 15 deletions
diff --git a/libAACdec/src/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp
index 2666454..0c33a2b 100644
--- a/libAACdec/src/aacdec_drc.cpp
+++ b/libAACdec/src/aacdec_drc.cpp
@@ -130,7 +130,6 @@ void aacDecoder_drcInit (
/* init control fields */
self->enable = 0;
self->numThreads = 0;
- self->digitalNorm = 0;
/* init params */
pParams = &self->params;
@@ -139,12 +138,15 @@ void aacDecoder_drcInit (
pParams->usrCut = FL2FXCONST_DBL(0.0f);
pParams->boost = 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->applyDigitalNorm = 0;
pParams->applyHeavyCompression = 0;
/* initial program ref level = target ref level */
self->progRefLevel = pParams->targetRefLevel;
+ self->progRefLevelPresent = 0;
+ self->presMode = -1;
}
@@ -222,11 +224,12 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
return AAC_DEC_INVALID_HANDLE;
}
if (value < 0) {
- self->digitalNorm = 0;
+ self->params.applyDigitalNorm = 0;
+ self->params.targetRefLevel = -1;
}
else {
/* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */
- self->digitalNorm = 1;
+ self->params.applyDigitalNorm = 1;
if (self->params.targetRefLevel != (SCHAR)value) {
self->params.targetRefLevel = (SCHAR)value;
self->progRefLevel = (SCHAR)value; /* Always set the program reference level equal to the
@@ -234,6 +237,16 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
}
}
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:
if (value < 0 || value > 1) {
return AAC_DEC_SET_PARAM_FAIL;
@@ -278,7 +291,7 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
self->enable = ( (self->params.boost > (FIXP_DBL)0)
|| (self->params.cut > (FIXP_DBL)0)
|| (self->params.applyHeavyCompression != 0)
- || (self->digitalNorm == 1) );
+ || (self->params.targetRefLevel >= 0) );
return ErrorStatus;
@@ -539,7 +552,7 @@ static int aacDecoder_drcReadCompression (
UINT payloadPosition )
{
int bitCnt = 0;
- int dmxLevelsPresent, compressionPresent;
+ int dmxLevelsPresent, extensionPresent, compressionPresent;
int coarseGrainTcPresent, fineGrainTcPresent;
/* Move to the beginning of the DRC payload field */
@@ -561,8 +574,9 @@ static int aacDecoder_drcReadCompression (
return 0;
}
FDKreadBits(bs, 2); /* dolby_surround_mode */
- FDKreadBits(bs, 2); /* presentation_mode */
- if (FDKreadBits(bs, 2) != 0) { /* reserved, set to 0 */
+ pDrcBs->presMode = FDKreadBits(bs, 2); /* presentation_mode */
+ FDKreadBits(bs, 1); /* stereo_downmix_mode */
+ if (FDKreadBits(bs, 1) != 0) { /* reserved, set to 0 */
return 0;
}
@@ -571,9 +585,7 @@ static int aacDecoder_drcReadCompression (
return 0;
}
dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
- if (FDKreadBits(bs, 1) != 0) { /* reserved, set to 0 */
- return 0;
- }
+ extensionPresent = FDKreadBits(bs, 1); /* ancillary_data_extension_status; */
compressionPresent = FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
coarseGrainTcPresent = FDKreadBits(bs, 1); /* coarse_grain_timecode_status */
fineGrainTcPresent = FDKreadBits(bs, 1); /* fine_grain_timecode_status */
@@ -631,6 +643,19 @@ static int aacDecoder_drcReadCompression (
bitCnt += 16;
}
+ /* Read extension just to get the right amount of bits. */
+ if (extensionPresent) {
+ int extBits = 8;
+
+ FDKreadBits(bs, 1); /* reserved, set to 0 */
+ if (FDKreadBits(bs, 1)) extBits += 8; /* ext_downmixing_levels_status */
+ if (FDKreadBits(bs, 1)) extBits += 16; /* ext_downmixing_global_gains_status */
+ if (FDKreadBits(bs, 1)) extBits += 8; /* ext_downmixing_lfe_level_status */
+
+ FDKpushFor(bs, extBits - 4); /* skip the extension payload remainder. */
+ bitCnt += extBits;
+ }
+
return (bitCnt);
}
@@ -780,9 +805,15 @@ static int aacDecoder_drcExtractAndMap (
*/
if (pThreadBs->progRefLevel >= 0) {
self->progRefLevel = pThreadBs->progRefLevel;
+ self->progRefLevelPresent = 1;
self->prlExpiryCount = 0; /* Got a new value -> Reset counter */
}
+ if (drcPayloadType == DVB_DRC_ANC_DATA) {
+ /* Announce the presentation mode of this valid thread. */
+ self->presMode = pThreadBs->presMode;
+ }
+
/* SCE, CPE and LFE */
for (ch = 0; ch < validChannels; ch++) {
int mapedChannel = channelMapping[ch];
@@ -802,6 +833,7 @@ static int aacDecoder_drcExtractAndMap (
if ( (pParams->expiryFrame > 0)
&& (self->prlExpiryCount++ > pParams->expiryFrame) )
{ /* The program reference level is too old, so set it back to the target level. */
+ self->progRefLevelPresent = 0;
self->progRefLevel = pParams->targetRefLevel;
self->prlExpiryCount = 0;
}
@@ -815,6 +847,7 @@ void aacDecoder_drcApply (
void *pSbrDec,
CAacDecoderChannelInfo *pAacDecoderChannelInfo,
CDrcChannelData *pDrcChData,
+ FIXP_DBL *extGain,
int ch, /* needed only for SBR */
int aacFrameSize,
int bSbrPresent )
@@ -826,8 +859,8 @@ void aacDecoder_drcApply (
FIXP_DBL max_mantissa;
INT max_exponent;
- FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.0f);
- INT norm_exponent = 0;
+ FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.5f);
+ INT norm_exponent = 1;
FIXP_DBL fact_mantissa[MAX_DRC_BANDS];
INT fact_exponent[MAX_DRC_BANDS];
@@ -849,6 +882,15 @@ void aacDecoder_drcApply (
if (!self->enable) {
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;
}
@@ -864,7 +906,7 @@ void aacDecoder_drcApply (
reduced DAC SNR (if signal is attenuated) or clipping (if signal is
boosted) */
- if (self->digitalNorm == 1)
+ if (pParams->targetRefLevel >= 0)
{
/* 0.5^((targetRefLevel - progRefLevel)/24) */
norm_mantissa = fLdPow(
@@ -874,7 +916,18 @@ void aacDecoder_drcApply (
3,
&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_exponent = 1;
}
@@ -1112,3 +1165,24 @@ int aacDecoder_drcEpilog (
return err;
}
+/*
+ * Export relevant metadata info from bitstream payload.
+ */
+void aacDecoder_drcGetInfo (
+ HANDLE_AAC_DRC self,
+ SCHAR *pPresMode,
+ SCHAR *pProgRefLevel )
+{
+ if (self != NULL) {
+ if (pPresMode != NULL) {
+ *pPresMode = self->presMode;
+ }
+ if (pProgRefLevel != NULL) {
+ if (self->progRefLevelPresent) {
+ *pProgRefLevel = self->progRefLevel;
+ } else {
+ *pProgRefLevel = -1;
+ }
+ }
+ }
+}