Commit 6ccecbc4 authored by Martin Storsjo's avatar Martin Storsjo

Merge remote-tracking branch 'aosp/master'

parents ce186344 d149516e
...@@ -53,6 +53,11 @@ LOCAL_C_INCLUDES := \ ...@@ -53,6 +53,11 @@ LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/libSBRdec/include \ $(LOCAL_PATH)/libSBRdec/include \
$(LOCAL_PATH)/libSBRenc/include $(LOCAL_PATH)/libSBRenc/include
# In tpdec_asc.cpp: address of array 'pPce->FrontElementIsCpe'
# will always evaluate to 'true'.
LOCAL_CLANG_CPPFLAGS += \
-Wno-pointer-bool-conversion
LOCAL_MODULE:= libFraunhoferAAC LOCAL_MODULE:= libFraunhoferAAC
include $(BUILD_STATIC_LIBRARY) include $(BUILD_STATIC_LIBRARY)
This diff is collapsed.
This diff is collapsed.
...@@ -108,15 +108,15 @@ C_ALLOC_MEM(AacDecoder, AAC_DECODER_INSTANCE, 1) ...@@ -108,15 +108,15 @@ C_ALLOC_MEM(AacDecoder, AAC_DECODER_INSTANCE, 1)
/*! The structure CAacDecoderStaticChannelInfo contains the static sideinfo which is needed /*! The structure CAacDecoderStaticChannelInfo contains the static sideinfo which is needed
for the decoding of one aac channel. <br> for the decoding of one aac channel. <br>
Dimension: #AacDecoderChannels */ Dimension: #AacDecoderChannels */
C_ALLOC_MEM2(AacDecoderStaticChannelInfo, CAacDecoderStaticChannelInfo, 1, (6)) C_ALLOC_MEM2(AacDecoderStaticChannelInfo, CAacDecoderStaticChannelInfo, 1, (8))
/*! The structure CAacDecoderChannelInfo contains the dynamic sideinfo which is needed /*! The structure CAacDecoderChannelInfo contains the dynamic sideinfo which is needed
for the decoding of one aac channel. <br> for the decoding of one aac channel. <br>
Dimension: #AacDecoderChannels */ Dimension: #AacDecoderChannels */
C_ALLOC_MEM2(AacDecoderChannelInfo, CAacDecoderChannelInfo, 1, (6)) C_AALLOC_MEM2(AacDecoderChannelInfo, CAacDecoderChannelInfo, 1, (8))
/*! Overlap buffer */ /*! Overlap buffer */
C_ALLOC_MEM2(OverlapBuffer, FIXP_DBL, OverlapBufferSize, (6)) C_ALLOC_MEM2(OverlapBuffer, FIXP_DBL, OverlapBufferSize, (8))
C_ALLOC_MEM(DrcInfo, CDrcInfo, 1) C_ALLOC_MEM(DrcInfo, CDrcInfo, 1)
...@@ -128,7 +128,7 @@ C_ALLOC_MEM(DrcInfo, CDrcInfo, 1) ...@@ -128,7 +128,7 @@ C_ALLOC_MEM(DrcInfo, CDrcInfo, 1)
Dynamic memory areas, might be reused in other algorithm sections, Dynamic memory areas, might be reused in other algorithm sections,
e.g. the sbr decoder e.g. the sbr decoder
*/ */
C_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL, ((6)*1024), SECT_DATA_L2, WORKBUFFER2_TAG) C_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL, ((8)*1024), SECT_DATA_L2, WORKBUFFER2_TAG)
C_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1, 1, SECT_DATA_L1, WORKBUFFER1_TAG) C_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1, 1, SECT_DATA_L1, WORKBUFFER1_TAG)
......
...@@ -1777,42 +1777,62 @@ const FIXP_TCC FDKaacDec_tnsCoeff4 [16] = ...@@ -1777,42 +1777,62 @@ const FIXP_TCC FDKaacDec_tnsCoeff4 [16] =
}; };
/* MPEG like mapping (no change). */ /* MPEG like mapping (no change). */
const UCHAR channelMappingTablePassthrough[8][8] = const UCHAR channelMappingTablePassthrough[15][8] =
{ {
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* fallback */
{ 0, 1,255,255,255,255,255,255}, /* mono / PS */ { 0, 1,255,255,255,255,255,255}, /* mono / PS */
{ 0, 1,255,255,255,255,255,255}, /* stereo */ { 0, 1,255,255,255,255,255,255}, /* stereo */
{ 0, 1, 2,255,255,255,255,255}, /* 3ch */ { 0, 1, 2,255,255,255,255,255}, /* 3ch */
{ 0, 1, 2, 3,255,255,255,255}, /* 4ch */ { 0, 1, 2, 3,255,255,255,255}, /* 4ch */
{ 0, 1, 2, 3, 4,255,255,255}, /* 5ch */ { 0, 1, 2, 3, 4,255,255,255}, /* 5ch */
{ 0, 1, 2, 3, 4, 5,255,255}, /* 5.1ch */ { 0, 1, 2, 3, 4, 5,255,255}, /* 5.1ch */
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* 7ch */ { 0, 1, 2, 3, 4, 5, 6, 7}, /* 7.1 front */
{ 0, 1, 2, 3, 4, 5, 6, 7} /* 7.1ch */ { 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
{ 0, 1, 2, 3, 4, 5, 6,255}, /* 6.1ch */
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* 7.1 rear */
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
{ 0, 1, 2, 3, 4, 5, 6, 7} /* 7.1 top */
}; };
/* WAV file like mapping (from MPEG mapping). */ /* WAV file like mapping (from MPEG mapping). */
const UCHAR channelMappingTableWAV[8][8] = const UCHAR channelMappingTableWAV[15][8] =
{ {
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* fallback */
{ 0, 1,255,255,255,255,255,255}, /* mono / PS */ { 0, 1,255,255,255,255,255,255}, /* mono / PS */
{ 0, 1,255,255,255,255,255,255}, /* stereo */ { 0, 1,255,255,255,255,255,255}, /* stereo */
{ 2, 0, 1,255,255,255,255,255}, /* 3ch */ { 2, 0, 1,255,255,255,255,255}, /* 3ch */
{ 2, 0, 1, 3,255,255,255,255}, /* 4ch */ { 2, 0, 1, 3,255,255,255,255}, /* 4ch */
{ 2, 0, 1, 3, 4,255,255,255}, /* 5ch */ { 2, 0, 1, 3, 4,255,255,255}, /* 5ch */
{ 2, 0, 1, 4, 5, 3,255,255}, /* 5.1ch */ { 2, 0, 1, 4, 5, 3,255,255}, /* 5.1ch */
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* 7ch */ { 2, 6, 7, 0, 1, 4, 5, 3}, /* 7.1 front */
{ 2, 0, 1, 6, 7, 4, 5, 3} /* 7.1ch */ { 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
{ 2, 0, 1, 4, 5, 6, 3,255}, /* 6.1ch */
{ 2, 0, 1, 6, 7, 4, 5, 3}, /* 7.1 rear */
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
{ 2, 0, 1, 4, 5, 3, 6, 7} /* 7.1 top */
}; };
/* Lookup tables for elements in ER bitstream */ /* Lookup tables for elements in ER bitstream */
const MP4_ELEMENT_ID elementsTab[8][7] = const MP4_ELEMENT_ID elementsTab[15][7] =
{ {
{ID_SCE, ID_EXT, ID_END, ID_NONE, ID_NONE,ID_NONE,ID_NONE }, /* 1 channel */ /* 1 */ { ID_SCE, ID_EXT, ID_END, ID_NONE, ID_NONE, ID_NONE, ID_NONE }, /* 1 channel */
{ID_CPE, ID_EXT, ID_END, ID_NONE, ID_NONE,ID_NONE,ID_NONE } /* 2 channels */ /* 2 */ { ID_CPE, ID_EXT, ID_END, ID_NONE, ID_NONE, ID_NONE, ID_NONE } /* 2 channels */
, /* 3 */ ,{ ID_SCE, ID_CPE, ID_EXT, ID_END, ID_NONE, ID_NONE, ID_NONE }, /* 3 channels */
{ID_SCE, ID_CPE, ID_EXT, ID_END, ID_NONE,ID_NONE,ID_NONE }, /* 3 channels */ /* 4 */ { ID_SCE, ID_CPE, ID_SCE, ID_EXT, ID_END, ID_NONE, ID_NONE }, /* 4 channels */
{ID_SCE, ID_CPE, ID_SCE, ID_EXT, ID_END, ID_NONE,ID_NONE }, /* 4 channels */ /* 5 */ { ID_SCE, ID_CPE, ID_CPE, ID_EXT, ID_END, ID_NONE, ID_NONE }, /* 5 channels */
{ID_SCE, ID_CPE, ID_CPE, ID_EXT, ID_END, ID_NONE,ID_NONE }, /* 5 channels */ /* 6 */ { ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_EXT, ID_END, ID_NONE } /* 6 channels */
{ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_EXT, ID_END, ID_NONE }, /* 6 channels */ /* 7 */ ,{ ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_EXT, ID_END }, /* 8 channels */
{ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_EXT, ID_END} /* 8 channels */ /* 8 */ { ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE }, /* reserved */
/* 9 */ { ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE }, /* reserved */
/* 10 */ { ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE }, /* reserved */
/* 11 */ { ID_SCE, ID_CPE, ID_CPE, ID_SCE, ID_LFE, ID_EXT, ID_END }, /* 7 channels */
/* 12 */ { ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_EXT, ID_END }, /* 8 channels */
/* 13 */ { ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE }, /* reserved */
/* 14 */ { ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_CPE, ID_EXT, ID_END } /* 8 channels */
}; };
/*! Random sign bit used for concealment /*! Random sign bit used for concealment
......
...@@ -177,11 +177,12 @@ extern const USHORT randomSign[AAC_NF_NO_RANDOM_VAL/16]; ...@@ -177,11 +177,12 @@ extern const USHORT randomSign[AAC_NF_NO_RANDOM_VAL/16];
extern const FIXP_DBL pow2_div24minus1[47]; extern const FIXP_DBL pow2_div24minus1[47];
extern const int offsetTab[2][16]; extern const int offsetTab[2][16];
/* Channel mapping indices for time domain I/O. First dimension is channel count-1. */ /* Channel mapping indices for time domain I/O.
extern const UCHAR channelMappingTablePassthrough[8][8]; The first dimension is the channel configuration index. */
extern const UCHAR channelMappingTableWAV[8][8]; extern const UCHAR channelMappingTablePassthrough[15][8];
extern const UCHAR channelMappingTableWAV[15][8];
/* Lookup tables for elements in ER bitstream */ /* Lookup tables for elements in ER bitstream */
extern const MP4_ELEMENT_ID elementsTab[8][7]; extern const MP4_ELEMENT_ID elementsTab[15][7];
#endif /* #ifndef AAC_ROM_H */ #endif /* #ifndef AAC_ROM_H */
...@@ -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,12 +138,15 @@ void aacDecoder_drcInit ( ...@@ -139,12 +138,15 @@ 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 */
self->progRefLevel = pParams->targetRefLevel; self->progRefLevel = pParams->targetRefLevel;
self->progRefLevelPresent = 0;
self->presMode = -1;
} }
...@@ -222,11 +224,12 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( ...@@ -222,11 +224,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 +237,16 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( ...@@ -234,6 +237,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 +291,7 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( ...@@ -278,7 +291,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;
...@@ -539,7 +552,7 @@ static int aacDecoder_drcReadCompression ( ...@@ -539,7 +552,7 @@ static int aacDecoder_drcReadCompression (
UINT payloadPosition ) UINT payloadPosition )
{ {
int bitCnt = 0; int bitCnt = 0;
int dmxLevelsPresent, compressionPresent; int dmxLevelsPresent, extensionPresent, compressionPresent;
int coarseGrainTcPresent, fineGrainTcPresent; int coarseGrainTcPresent, fineGrainTcPresent;
/* Move to the beginning of the DRC payload field */ /* Move to the beginning of the DRC payload field */
...@@ -561,8 +574,9 @@ static int aacDecoder_drcReadCompression ( ...@@ -561,8 +574,9 @@ static int aacDecoder_drcReadCompression (
return 0; return 0;
} }
FDKreadBits(bs, 2); /* dolby_surround_mode */ FDKreadBits(bs, 2); /* dolby_surround_mode */
FDKreadBits(bs, 2); /* presentation_mode */ pDrcBs->presMode = FDKreadBits(bs, 2); /* presentation_mode */
if (FDKreadBits(bs, 2) != 0) { /* reserved, set to 0 */ FDKreadBits(bs, 1); /* stereo_downmix_mode */
if (FDKreadBits(bs, 1) != 0) { /* reserved, set to 0 */
return 0; return 0;
} }
...@@ -571,9 +585,7 @@ static int aacDecoder_drcReadCompression ( ...@@ -571,9 +585,7 @@ static int aacDecoder_drcReadCompression (
return 0; return 0;
} }
dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */ dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
if (FDKreadBits(bs, 1) != 0) { /* reserved, set to 0 */ extensionPresent = FDKreadBits(bs, 1); /* ancillary_data_extension_status; */
return 0;
}
compressionPresent = FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */ compressionPresent = FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
coarseGrainTcPresent = FDKreadBits(bs, 1); /* coarse_grain_timecode_status */ coarseGrainTcPresent = FDKreadBits(bs, 1); /* coarse_grain_timecode_status */
fineGrainTcPresent = FDKreadBits(bs, 1); /* fine_grain_timecode_status */ fineGrainTcPresent = FDKreadBits(bs, 1); /* fine_grain_timecode_status */
...@@ -631,6 +643,19 @@ static int aacDecoder_drcReadCompression ( ...@@ -631,6 +643,19 @@ static int aacDecoder_drcReadCompression (
bitCnt += 16; 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); return (bitCnt);
} }
...@@ -780,9 +805,15 @@ static int aacDecoder_drcExtractAndMap ( ...@@ -780,9 +805,15 @@ static int aacDecoder_drcExtractAndMap (
*/ */
if (pThreadBs->progRefLevel >= 0) { if (pThreadBs->progRefLevel >= 0) {
self->progRefLevel = pThreadBs->progRefLevel; self->progRefLevel = pThreadBs->progRefLevel;
self->progRefLevelPresent = 1;
self->prlExpiryCount = 0; /* Got a new value -> Reset counter */ 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 */ /* SCE, CPE and LFE */
for (ch = 0; ch < validChannels; ch++) { for (ch = 0; ch < validChannels; ch++) {
int mapedChannel = channelMapping[ch]; int mapedChannel = channelMapping[ch];
...@@ -802,6 +833,7 @@ static int aacDecoder_drcExtractAndMap ( ...@@ -802,6 +833,7 @@ static int aacDecoder_drcExtractAndMap (
if ( (pParams->expiryFrame > 0) if ( (pParams->expiryFrame > 0)
&& (self->prlExpiryCount++ > pParams->expiryFrame) ) && (self->prlExpiryCount++ > pParams->expiryFrame) )
{ /* The program reference level is too old, so set it back to the target level. */ { /* The program reference level is too old, so set it back to the target level. */
self->progRefLevelPresent = 0;
self->progRefLevel = pParams->targetRefLevel; self->progRefLevel = pParams->targetRefLevel;
self->prlExpiryCount = 0; self->prlExpiryCount = 0;
} }
...@@ -815,6 +847,7 @@ void aacDecoder_drcApply ( ...@@ -815,6 +847,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 )
...@@ -826,8 +859,8 @@ void aacDecoder_drcApply ( ...@@ -826,8 +859,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];
...@@ -849,6 +882,15 @@ void aacDecoder_drcApply ( ...@@ -849,6 +882,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;
} }
...@@ -864,7 +906,7 @@ void aacDecoder_drcApply ( ...@@ -864,7 +906,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(
...@@ -874,7 +916,18 @@ void aacDecoder_drcApply ( ...@@ -874,7 +916,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;
} }
...@@ -1112,3 +1165,24 @@ int aacDecoder_drcEpilog ( ...@@ -1112,3 +1165,24 @@ int aacDecoder_drcEpilog (
return err; 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;
}
}
}
}
...@@ -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 );
...@@ -170,5 +173,17 @@ int aacDecoder_drcEpilog ( ...@@ -170,5 +173,17 @@ int aacDecoder_drcEpilog (
UCHAR channelMapping[], UCHAR channelMapping[],
int validChannels ); int validChannels );
/**
* \brief Get metadata information found in bitstream.
* \param self DRC module instance handle.
* \param pPresMode Pointer to field where the presentation mode will be written to.
* \param pProgRefLevel Pointer to field where the program reference level will be written to.
* \return Nothing.
*/
void aacDecoder_drcGetInfo (
HANDLE_AAC_DRC self,
SCHAR *pPresMode,
SCHAR *pProgRefLevel );
#endif /* AACDEC_DRC_H */ #endif /* AACDEC_DRC_H */
...@@ -124,6 +124,7 @@ typedef struct ...@@ -124,6 +124,7 @@ typedef struct
{ {
UINT excludedChnsMask; UINT excludedChnsMask;
SCHAR progRefLevel; SCHAR progRefLevel;
SCHAR presMode; /* Presentation mode: 0 (not indicated), 1, 2, and 3 (reserved). */
SCHAR pceInstanceTag; SCHAR pceInstanceTag;
CDrcChannelData channelData; CDrcChannelData channelData;
...@@ -140,6 +141,7 @@ typedef struct ...@@ -140,6 +141,7 @@ typedef struct
UINT expiryFrame; UINT expiryFrame;
SCHAR targetRefLevel; SCHAR targetRefLevel;
UCHAR bsDelayEnable; UCHAR bsDelayEnable;
UCHAR applyDigitalNorm;
UCHAR applyHeavyCompression; UCHAR applyHeavyCompression;
} CDrcParams; } CDrcParams;
...@@ -155,9 +157,11 @@ typedef struct ...@@ -155,9 +157,11 @@ typedef struct
USHORT numPayloads; /* The number of DRC data payload elements found within frame */ USHORT numPayloads; /* The number of DRC data payload elements found within frame */
USHORT numThreads; /* The number of DRC data threads extracted from the found payload elements */ USHORT numThreads; /* The number of DRC data threads extracted from the found payload elements */
SCHAR progRefLevel; /* Program reference level for all channels */ SCHAR progRefLevel; /* Program reference level for all channels */
UCHAR progRefLevelPresent; /* Program reference level found in bitstream */
UINT prlExpiryCount; /* Counter that can be used to monitor the life time of the program reference level. */ UINT prlExpiryCount; /* Counter that can be used to monitor the life time of the program reference level. */
SCHAR presMode; /* Presentation mode as defined in ETSI TS 101 154 */
UCHAR dvbAncDataAvailable; /* Flag that indicates whether DVB ancillary data is present or not */ UCHAR dvbAncDataAvailable; /* Flag that indicates whether DVB ancillary data is present or not */
UINT dvbAncDataPosition; /* Used to store the DVB ancillary data payload position in the bitstream (only one per frame) */ UINT dvbAncDataPosition; /* Used to store the DVB ancillary data payload position in the bitstream (only one per frame) */
UINT drcPayloadPosition[MAX_DRC_THREADS]; /* Used to store the DRC payload positions in the bitstream */ UINT drcPayloadPosition[MAX_DRC_THREADS]; /* Used to store the DRC payload positions in the bitstream */
......
This diff is collapsed.
...@@ -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 */
...@@ -176,27 +177,31 @@ struct AAC_DECODER_INSTANCE { ...@@ -176,27 +177,31 @@ struct AAC_DECODER_INSTANCE {
UINT flags; /*!< Flags for internal decoder use. DO NOT USE self::streaminfo::flags ! */ UINT flags; /*!< Flags for internal decoder use. DO NOT USE self::streaminfo::flags ! */
MP4_ELEMENT_ID elements[7]; /*!< Table where the element Id's are listed */ MP4_ELEMENT_ID elements[(8)]; /*!< Table where the element Id's are listed */
UCHAR elTags[7]; /*!< Table where the elements id Tags are listed */ UCHAR elTags[(8)]; /*!< Table where the elements id Tags are listed */
UCHAR chMapping[(6)]; /*!< Table of MPEG canonical order to bitstream channel order mapping. */ UCHAR chMapping[(8)]; /*!< Table of MPEG canonical order to bitstream channel order mapping. */
AUDIO_CHANNEL_TYPE channelType[(6)]; /*!< Audio channel type of each output audio channel (from 0 upto numChannels). */ AUDIO_CHANNEL_TYPE channelType[(8)]; /*!< Audio channel type of each output audio channel (from 0 upto numChannels). */
UCHAR channelIndices[(6)]; /*!< Audio channel index for each output audio channel (from 0 upto numChannels). */ UCHAR channelIndices[(8)]; /*!< Audio channel index for each output audio channel (from 0 upto numChannels). */
/* See ISO/IEC 13818-7:2005(E), 8.5.3.2 Explicit channel mapping using a program_config_element() */ /* See ISO/IEC 13818-7:2005(E), 8.5.3.2 Explicit channel mapping using a program_config_element() */
const UCHAR (*channelOutputMapping)[8]; /*!< Table for MPEG canonical order to output channel order mapping. */ const UCHAR (*channelOutputMapping)[8]; /*!< Table for MPEG canonical order to output channel order mapping. */
UCHAR chMapIndex; /*!< Index to access one line of the channelOutputMapping table. This is required
because not all 8 channel configurations have the same output mapping. */
CProgramConfig pce; CProgramConfig pce;
CStreamInfo streamInfo; /*!< pointer to StreamInfo data (read from the bitstream) */ CStreamInfo streamInfo; /*!< pointer to StreamInfo data (read from the bitstream) */
CAacDecoderChannelInfo *pAacDecoderChannelInfo[(6)]; /*!< Temporal channel memory */ CAacDecoderChannelInfo *pAacDecoderChannelInfo[(8)]; /*!< Temporal channel memory */
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[(6)]; /*!< Persistent channel memory */ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[(8)]; /*!< Persistent channel memory */
CAacDecoderCommonData aacCommonData; /*!< Temporal shared data for all channels hooked into pAacDecoderChannelInfo */ CAacDecoderCommonData aacCommonData; /*!< Temporal shared data for all channels hooked into pAacDecoderChannelInfo */
CConcealParams concealCommonData; CConcealParams concealCommonData;
INT concealChannels;
INT aacChannelsPrev; /*!< The amount of AAC core channels of the last successful decode call. */
AUDIO_CHANNEL_TYPE channelTypePrev[(8)]; /*!< Array holding the channelType values of the last successful decode call. */
UCHAR channelIndicesPrev[(8)]; /*!< Array holding the channelIndices values of the last successful decode call. */
HANDLE_SBRDECODER hSbrDecoder; /*!< SBR decoder handle. */ HANDLE_SBRDECODER hSbrDecoder; /*!< SBR decoder handle. */
...@@ -214,6 +219,12 @@ struct AAC_DECODER_INSTANCE { ...@@ -214,6 +219,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. */
}; };
......
This diff is collapsed.
...@@ -762,7 +762,6 @@ int ...@@ -762,7 +762,6 @@ int
CConcealment_UpdateState( hConcealmentInfo, CConcealment_UpdateState( hConcealmentInfo,
frameOk ); frameOk );
if ( !frameOk )
{ {
/* Create data for signal rendering according to the selected concealment method and decoder operating mode. */ /* Create data for signal rendering according to the selected concealment method and decoder operating mode. */
...@@ -775,11 +774,13 @@ int ...@@ -775,11 +774,13 @@ int
{ {
default: default:
case ConcealMethodMute: case ConcealMethodMute:
if (!frameOk) {
/* Mute spectral data in case of errors */ /* Mute spectral data in case of errors */
FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL)); FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
/* Set last window shape */ /* Set last window shape */
pAacDecoderChannelInfo->icsInfo.WindowShape = hConcealmentInfo->windowShape; pAacDecoderChannelInfo->icsInfo.WindowShape = hConcealmentInfo->windowShape;
appliedProcessing = 1; appliedProcessing = 1;
}
break; break;
case ConcealMethodNoise: case ConcealMethodNoise:
...@@ -801,7 +802,7 @@ int ...@@ -801,7 +802,7 @@ int
pSamplingRateInfo, pSamplingRateInfo,
samplesPerFrame, samplesPerFrame,
0, /* don't use tonal improvement */ 0, /* don't use tonal improvement */
0); frameOk);
break; break;
} }
......
...@@ -215,7 +215,7 @@ amm-info@iis.fraunhofer.de ...@@ -215,7 +215,7 @@ amm-info@iis.fraunhofer.de
#else #else
#error >>>> Please set architecture characterization defines for your platform (FDK_HIGH_PERFORMANCE)! <<<< #warning >>>> Please set architecture characterization defines for your platform (FDK_HIGH_PERFORMANCE)! <<<<
#endif /* Architecture switches */ #endif /* Architecture switches */
......
...@@ -96,7 +96,7 @@ amm-info@iis.fraunhofer.de ...@@ -96,7 +96,7 @@ amm-info@iis.fraunhofer.de
#if defined(__CC_ARM) || defined(__arm__) || defined(_M_ARM) /* cppp replaced: elif */ #if defined(__CC_ARM) || defined(__arm__) || defined(_M_ARM) /* cppp replaced: elif */
#include "arm/cplx_mul.h" #include "arm/cplx_mul.h"
#elif defined(__GNUC__) && defined(__mips__) /* cppp replaced: elif */ #elif defined(__GNUC__) && defined(__mips__) && __mips_isa_rev < 6
#include "mips/cplx_mul.h" #include "mips/cplx_mul.h"
#endif /* #if defined all cores: bfin, arm, etc. */ #endif /* #if defined all cores: bfin, arm, etc. */
......
...@@ -89,7 +89,7 @@ amm-info@iis.fraunhofer.de ...@@ -89,7 +89,7 @@ amm-info@iis.fraunhofer.de
******************************************************************************/ ******************************************************************************/
#if defined(__GNUC__) && defined(__mips__) #if defined(__GNUC__) && defined(__mips__) && __mips_isa_rev < 6
//#define FUNCTION_cplxMultDiv2_32x16 //#define FUNCTION_cplxMultDiv2_32x16
......
...@@ -146,12 +146,15 @@ typedef struct ...@@ -146,12 +146,15 @@ typedef struct
UCHAR FrontElementIsCpe[PC_FSB_CHANNELS_MAX]; UCHAR FrontElementIsCpe[PC_FSB_CHANNELS_MAX];
UCHAR FrontElementTagSelect[PC_FSB_CHANNELS_MAX]; UCHAR FrontElementTagSelect[PC_FSB_CHANNELS_MAX];
UCHAR FrontElementHeightInfo[PC_FSB_CHANNELS_MAX];
UCHAR SideElementIsCpe[PC_FSB_CHANNELS_MAX]; UCHAR SideElementIsCpe[PC_FSB_CHANNELS_MAX];
UCHAR SideElementTagSelect[PC_FSB_CHANNELS_MAX]; UCHAR SideElementTagSelect[PC_FSB_CHANNELS_MAX];
UCHAR SideElementHeightInfo[PC_FSB_CHANNELS_MAX];
UCHAR BackElementIsCpe[PC_FSB_CHANNELS_MAX]; UCHAR BackElementIsCpe[PC_FSB_CHANNELS_MAX];
UCHAR BackElementTagSelect[PC_FSB_CHANNELS_MAX]; UCHAR BackElementTagSelect[PC_FSB_CHANNELS_MAX];
UCHAR BackElementHeightInfo[PC_FSB_CHANNELS_MAX];
UCHAR LfeElementTagSelect[PC_LFE_CHANNELS_MAX]; UCHAR LfeElementTagSelect[PC_LFE_CHANNELS_MAX];
...@@ -324,16 +327,23 @@ int getSamplingRateIndex( UINT samplingRate ) ...@@ -324,16 +327,23 @@ int getSamplingRateIndex( UINT samplingRate )
*/ */
static inline int getNumberOfTotalChannels(int channelConfig) static inline int getNumberOfTotalChannels(int channelConfig)
{ {
if (channelConfig > 0 && channelConfig < 8) switch (channelConfig) {
return (channelConfig == 7)?8:channelConfig; case 1: case 2: case 3:
else case 4: case 5: case 6:
return channelConfig;
case 7: case 12: case 14:
return 8;
case 11:
return 7;
default:
return 0; return 0;
}
} }
static inline static inline
int getNumberOfEffectiveChannels(const int channelConfig) int getNumberOfEffectiveChannels(const int channelConfig)
{ { /* index: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 */
const int n[] = {0,1,2,3,4,5,5,7}; const int n[] = {0,1,2,3,4,5,5,7,0,0, 0, 6, 7, 0, 7, 0};
return n[channelConfig]; return n[channelConfig];
} }
......
...@@ -151,6 +151,7 @@ typedef enum { ...@@ -151,6 +151,7 @@ typedef enum {
#define PC_ASSOCDATA_MAX 8 #define PC_ASSOCDATA_MAX 8
#define PC_CCEL_MAX 16 /* CC elements */ #define PC_CCEL_MAX 16 /* CC elements */
#define PC_COMMENTLENGTH 256 #define PC_COMMENTLENGTH 256
#define PC_NUM_HEIGHT_LAYER 3
/*! /*!
...@@ -239,14 +240,20 @@ int CProgramConfig_LookupElement( ...@@ -239,14 +240,20 @@ int CProgramConfig_LookupElement(
); );
/** /**
* \brief Get table of elements in canonical order. * \brief Get table of elements in canonical order from a
* give program config field.
* \param pPce A valid program config structure. * \param pPce A valid program config structure.
* \param table An array where the element IDs are stored. * \param table An array where the element IDs are stored.
* \param elListSize The length of the table array.
* \param pChMapIdx Pointer to a field receiving the corresponding
* implicit channel configuration index of the given
* PCE. If none can be found it receives the value 0.
* \return Total element count including all SCE, CPE and LFE. * \return Total element count including all SCE, CPE and LFE.
*/ */
int CProgramConfig_GetElementTable( const CProgramConfig *pPce, int CProgramConfig_GetElementTable( const CProgramConfig *pPce,
MP4_ELEMENT_ID table[], MP4_ELEMENT_ID table[],
const INT elListSize ); const INT elListSize,
UCHAR *pChMapIdx );
/** /**
* \brief Initialize a given AudioSpecificConfig structure. * \brief Initialize a given AudioSpecificConfig structure.
......
This diff is collapsed.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
/* library info */ /* library info */
#define TP_LIB_VL0 2 #define TP_LIB_VL0 2
#define TP_LIB_VL1 3 #define TP_LIB_VL1 3
#define TP_LIB_VL2 3 #define TP_LIB_VL2 4
#define TP_LIB_TITLE "MPEG Transport" #define TP_LIB_TITLE "MPEG Transport"
#define TP_LIB_BUILD_DATE __DATE__ #define TP_LIB_BUILD_DATE __DATE__
#define TP_LIB_BUILD_TIME __TIME__ #define TP_LIB_BUILD_TIME __TIME__
...@@ -146,12 +146,15 @@ typedef struct ...@@ -146,12 +146,15 @@ typedef struct
UCHAR FrontElementIsCpe[PC_FSB_CHANNELS_MAX]; UCHAR FrontElementIsCpe[PC_FSB_CHANNELS_MAX];
UCHAR FrontElementTagSelect[PC_FSB_CHANNELS_MAX]; UCHAR FrontElementTagSelect[PC_FSB_CHANNELS_MAX];
UCHAR FrontElementHeightInfo[PC_FSB_CHANNELS_MAX];
UCHAR SideElementIsCpe[PC_FSB_CHANNELS_MAX]; UCHAR SideElementIsCpe[PC_FSB_CHANNELS_MAX];
UCHAR SideElementTagSelect[PC_FSB_CHANNELS_MAX]; UCHAR SideElementTagSelect[PC_FSB_CHANNELS_MAX];
UCHAR SideElementHeightInfo[PC_FSB_CHANNELS_MAX];
UCHAR BackElementIsCpe[PC_FSB_CHANNELS_MAX]; UCHAR BackElementIsCpe[PC_FSB_CHANNELS_MAX];
UCHAR BackElementTagSelect[PC_FSB_CHANNELS_MAX]; UCHAR BackElementTagSelect[PC_FSB_CHANNELS_MAX];
UCHAR BackElementHeightInfo[PC_FSB_CHANNELS_MAX];
UCHAR LfeElementTagSelect[PC_LFE_CHANNELS_MAX]; UCHAR LfeElementTagSelect[PC_LFE_CHANNELS_MAX];
...@@ -324,16 +327,23 @@ int getSamplingRateIndex( UINT samplingRate ) ...@@ -324,16 +327,23 @@ int getSamplingRateIndex( UINT samplingRate )
*/ */
static inline int getNumberOfTotalChannels(int channelConfig) static inline int getNumberOfTotalChannels(int channelConfig)
{ {
if (channelConfig > 0 && channelConfig < 8) switch (channelConfig) {
return (channelConfig == 7)?8:channelConfig; case 1: case 2: case 3:
else case 4: case 5: case 6:
return channelConfig;
case 7: case 12: case 14:
return 8;
case 11:
return 7;
default:
return 0; return 0;
}
} }
static inline static inline
int getNumberOfEffectiveChannels(const int channelConfig) int getNumberOfEffectiveChannels(const int channelConfig)
{ { /* index: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 */
const int n[] = {0,1,2,3,4,5,5,7}; const int n[] = {0,1,2,3,4,5,5,7,0,0, 0, 6, 7, 0, 7, 0};
return n[channelConfig]; return n[channelConfig];
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
/* library info */ /* library info */
#define TP_LIB_VL0 2 #define TP_LIB_VL0 2
#define TP_LIB_VL1 3 #define TP_LIB_VL1 3
#define TP_LIB_VL2 3 #define TP_LIB_VL2 4
#define TP_LIB_TITLE "MPEG Transport" #define TP_LIB_TITLE "MPEG Transport"
#define TP_LIB_BUILD_DATE __DATE__ #define TP_LIB_BUILD_DATE __DATE__
#define TP_LIB_BUILD_TIME __TIME__ #define TP_LIB_BUILD_TIME __TIME__
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -145,6 +145,8 @@ typedef enum ...@@ -145,6 +145,8 @@ typedef enum
SBR_SYSTEM_BITSTREAM_DELAY, /*!< System: Switch to enable an additional SBR bitstream delay of one frame. */ SBR_SYSTEM_BITSTREAM_DELAY, /*!< System: Switch to enable an additional SBR bitstream delay of one frame. */
SBR_QMF_MODE, /*!< Set QMF mode, either complex or low power. */ SBR_QMF_MODE, /*!< Set QMF mode, either complex or low power. */
SBR_LD_QMF_TIME_ALIGN, /*!< Set QMF type, either LD-MPS or CLDFB. Relevant for ELD streams only. */ SBR_LD_QMF_TIME_ALIGN, /*!< Set QMF type, either LD-MPS or CLDFB. Relevant for ELD streams only. */
SBR_FLUSH_DATA, /*!< Set internal state to flush the decoder with the next process call. */
SBR_CLEAR_HISTORY, /*!< Clear all internal states (delay lines, QMF states, ...). */
SBR_BS_INTERRUPTION /*!< Signal bit stream interruption. Value is ignored. */ SBR_BS_INTERRUPTION /*!< Signal bit stream interruption. Value is ignored. */
} SBRDEC_PARAM; } SBRDEC_PARAM;
...@@ -308,7 +310,7 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self, ...@@ -308,7 +310,7 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self,
INT_PCM *timeData, INT_PCM *timeData,
int *numChannels, int *numChannels,
int *sampleRate, int *sampleRate,
const UCHAR channelMapping[(6)], const UCHAR channelMapping[(8)],
const int interleaved, const int interleaved,
const int coreDecodedOk, const int coreDecodedOk,
UCHAR *psDecoded ); UCHAR *psDecoded );
...@@ -329,6 +331,13 @@ SBR_ERROR sbrDecoder_Close ( HANDLE_SBRDECODER *self ); ...@@ -329,6 +331,13 @@ SBR_ERROR sbrDecoder_Close ( HANDLE_SBRDECODER *self );
*/ */
INT sbrDecoder_GetLibInfo( LIB_INFO *info ); INT sbrDecoder_GetLibInfo( LIB_INFO *info );
/**
* \brief Determine the modules output signal delay in samples.
* \param self SBR decoder handle.
* \return The number of samples signal delay added by the module.
*/
UINT sbrDecoder_GetDelay( const HANDLE_SBRDECODER self );
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -179,6 +179,9 @@ typedef FREQ_BAND_DATA *HANDLE_FREQ_BAND_DATA; ...@@ -179,6 +179,9 @@ typedef FREQ_BAND_DATA *HANDLE_FREQ_BAND_DATA;
#define SBRDEC_LOW_POWER 16 /* Flag indicating that Low Power QMF mode shall be used. */ #define SBRDEC_LOW_POWER 16 /* Flag indicating that Low Power QMF mode shall be used. */
#define SBRDEC_PS_DECODED 32 /* Flag indicating that PS was decoded and rendered. */ #define SBRDEC_PS_DECODED 32 /* Flag indicating that PS was decoded and rendered. */
#define SBRDEC_LD_MPS_QMF 512 /* Flag indicating that the LD-MPS QMF shall be used. */ #define SBRDEC_LD_MPS_QMF 512 /* Flag indicating that the LD-MPS QMF shall be used. */
#define SBRDEC_DOWNSAMPLE 8192 /* Flag indicating that the downsampling mode is used. */
#define SBRDEC_FLUSH 16384 /* Flag is used to flush all elements in use. */
#define SBRDEC_FORCE_RESET 32768 /* Flag is used to force a reset of all elements in use. */
#define SBRDEC_HDR_STAT_RESET 1 #define SBRDEC_HDR_STAT_RESET 1
#define SBRDEC_HDR_STAT_UPDATE 2 #define SBRDEC_HDR_STAT_UPDATE 2
......
...@@ -107,19 +107,19 @@ amm-info@iis.fraunhofer.de ...@@ -107,19 +107,19 @@ amm-info@iis.fraunhofer.de
/*! SBR Decoder main structure */ /*! SBR Decoder main structure */
C_ALLOC_MEM(Ram_SbrDecoder, struct SBR_DECODER_INSTANCE, 1) C_ALLOC_MEM(Ram_SbrDecoder, struct SBR_DECODER_INSTANCE, 1)
/*! SBR Decoder element data <br> /*! SBR Decoder element data <br>
Dimension: (4) */ Dimension: (8) */
C_ALLOC_MEM2(Ram_SbrDecElement, SBR_DECODER_ELEMENT, 1, (4)) C_ALLOC_MEM2(Ram_SbrDecElement, SBR_DECODER_ELEMENT, 1, (8))
/*! SBR Decoder individual channel data <br> /*! SBR Decoder individual channel data <br>
Dimension: (6) */ Dimension: (8) */
C_ALLOC_MEM2(Ram_SbrDecChannel, SBR_CHANNEL, 1, (6)+1) C_ALLOC_MEM2(Ram_SbrDecChannel, SBR_CHANNEL, 1, (8)+1)
/*! Filter states for QMF-synthesis. <br> /*! Filter states for QMF-synthesis. <br>
Dimension: #(6) * (#QMF_FILTER_STATE_SYN_SIZE-#(64)) */ Dimension: #(8) * (#QMF_FILTER_STATE_SYN_SIZE-#(64)) */
C_AALLOC_MEM2_L(Ram_sbr_QmfStatesSynthesis, FIXP_QSS, (640)-(64), (6)+1, SECT_DATA_L1) C_AALLOC_MEM2_L(Ram_sbr_QmfStatesSynthesis, FIXP_QSS, (640)-(64), (8)+1, SECT_DATA_L1)
/*! Delayed spectral data needed for the dynamic framing of SBR. /*! Delayed spectral data needed for the dynamic framing of SBR.
For mp3PRO, 1/3 of a frame is buffered (#(6) 6) */ For mp3PRO, 1/3 of a frame is buffered (#(6) 6) */
C_AALLOC_MEM2(Ram_sbr_OverlapBuffer, FIXP_DBL, 2 * (6) * (64), (6)+1) C_AALLOC_MEM2(Ram_sbr_OverlapBuffer, FIXP_DBL, 2 * (6) * (64), (8)+1)
/*! Static Data of PS */ /*! Static Data of PS */
......
...@@ -118,8 +118,8 @@ typedef struct ...@@ -118,8 +118,8 @@ typedef struct
struct SBR_DECODER_INSTANCE struct SBR_DECODER_INSTANCE
{ {
SBR_DECODER_ELEMENT *pSbrElement[(4)]; SBR_DECODER_ELEMENT *pSbrElement[(8)];
SBR_HEADER_DATA sbrHeader[(4)][(1)+1]; /* Sbr header for each individual channel of an element */ SBR_HEADER_DATA sbrHeader[(8)][(1)+1]; /* Sbr header for each individual channel of an element */
FIXP_DBL *workBuffer1; FIXP_DBL *workBuffer1;
FIXP_DBL *workBuffer2; FIXP_DBL *workBuffer2;
......
...@@ -95,7 +95,7 @@ amm-info@iis.fraunhofer.de ...@@ -95,7 +95,7 @@ amm-info@iis.fraunhofer.de
#define SBRDEC_MAX_DRC_CHANNELS (6) #define SBRDEC_MAX_DRC_CHANNELS (8)
#define SBRDEC_MAX_DRC_BANDS ( 16 ) #define SBRDEC_MAX_DRC_BANDS ( 16 )
typedef struct typedef struct
......
...@@ -137,7 +137,7 @@ amm-info@iis.fraunhofer.de ...@@ -137,7 +137,7 @@ amm-info@iis.fraunhofer.de
/* Decoder library info */ /* Decoder library info */
#define SBRDECODER_LIB_VL0 2 #define SBRDECODER_LIB_VL0 2
#define SBRDECODER_LIB_VL1 2 #define SBRDECODER_LIB_VL1 2
#define SBRDECODER_LIB_VL2 3 #define SBRDECODER_LIB_VL2 6
#define SBRDECODER_LIB_TITLE "SBR Decoder" #define SBRDECODER_LIB_TITLE "SBR Decoder"
#define SBRDECODER_LIB_BUILD_DATE __DATE__ #define SBRDECODER_LIB_BUILD_DATE __DATE__
#define SBRDECODER_LIB_BUILD_TIME __TIME__ #define SBRDECODER_LIB_BUILD_TIME __TIME__
...@@ -251,8 +251,10 @@ SBR_ERROR sbrDecoder_ResetElement ( ...@@ -251,8 +251,10 @@ SBR_ERROR sbrDecoder_ResetElement (
if ( sampleRateIn == sampleRateOut ) { if ( sampleRateIn == sampleRateOut ) {
synDownsampleFac = 2; synDownsampleFac = 2;
self->flags |= SBRDEC_DOWNSAMPLE;
} else { } else {
synDownsampleFac = 1; synDownsampleFac = 1;
self->flags &= ~SBRDEC_DOWNSAMPLE;
} }
self->synDownsampleFac = synDownsampleFac; self->synDownsampleFac = synDownsampleFac;
...@@ -428,7 +430,7 @@ SBR_ERROR sbrDecoder_InitElement ( ...@@ -428,7 +430,7 @@ SBR_ERROR sbrDecoder_InitElement (
int nSbrElementsStart = self->numSbrElements; int nSbrElementsStart = self->numSbrElements;
/* Check core codec AOT */ /* Check core codec AOT */
if (! sbrDecoder_isCoreCodecValid(coreCodec) || elementIndex >= (4)) { if (! sbrDecoder_isCoreCodecValid(coreCodec) || elementIndex >= (8)) {
sbrError = SBRDEC_UNSUPPORTED_CONFIG; sbrError = SBRDEC_UNSUPPORTED_CONFIG;
goto bail; goto bail;
} }
...@@ -444,6 +446,7 @@ SBR_ERROR sbrDecoder_InitElement ( ...@@ -444,6 +446,7 @@ SBR_ERROR sbrDecoder_InitElement (
&& self->coreCodec == coreCodec && self->coreCodec == coreCodec
&& self->pSbrElement[elementIndex] != NULL && self->pSbrElement[elementIndex] != NULL
&& self->pSbrElement[elementIndex]->elementID == elementID && self->pSbrElement[elementIndex]->elementID == elementID
&& !(self->flags & SBRDEC_FORCE_RESET)
) )
{ {
/* Nothing to do */ /* Nothing to do */
...@@ -550,8 +553,9 @@ bail: ...@@ -550,8 +553,9 @@ bail:
if (nSbrElementsStart < self->numSbrElements) { if (nSbrElementsStart < self->numSbrElements) {
/* Free the memory allocated for this element */ /* Free the memory allocated for this element */
sbrDecoder_DestroyElement( self, elementIndex ); sbrDecoder_DestroyElement( self, elementIndex );
} else if (self->pSbrElement[elementIndex] != NULL) { } else if ( (self->pSbrElement[elementIndex] != NULL)
/* Set error flag to trigger concealment */ && (elementIndex < (8)))
{ /* Set error flag to trigger concealment */
self->pSbrElement[elementIndex]->frameErrorFlag[self->pSbrElement[elementIndex]->useFrameSlot] = 1; self->pSbrElement[elementIndex]->frameErrorFlag[self->pSbrElement[elementIndex]->useFrameSlot] = 1;
} }
} }
...@@ -615,7 +619,7 @@ INT sbrDecoder_Header ( ...@@ -615,7 +619,7 @@ INT sbrDecoder_Header (
SBR_ERROR sbrError = SBRDEC_OK; SBR_ERROR sbrError = SBRDEC_OK;
int headerIndex; int headerIndex;
if ( self == NULL || elementIndex > (4) ) if ( self == NULL || elementIndex > (8) )
{ {
return SBRDEC_UNSUPPORTED_CONFIG; return SBRDEC_UNSUPPORTED_CONFIG;
} }
...@@ -728,6 +732,24 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self, ...@@ -728,6 +732,24 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self,
} }
} }
break; break;
case SBR_FLUSH_DATA:
if (value != 0) {
if (self == NULL) {
errorStatus = SBRDEC_NOT_INITIALIZED;
} else {
self->flags |= SBRDEC_FLUSH;
}
}
break;
case SBR_CLEAR_HISTORY:
if (value != 0) {
if (self == NULL) {
errorStatus = SBRDEC_NOT_INITIALIZED;
} else {
self->flags |= SBRDEC_FORCE_RESET;
}
}
break;
case SBR_BS_INTERRUPTION: case SBR_BS_INTERRUPTION:
{ {
int elementIndex; int elementIndex;
...@@ -738,7 +760,8 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self, ...@@ -738,7 +760,8 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self,
} }
/* Loop over SBR elements */ /* Loop over SBR elements */
for (elementIndex = 0; elementIndex < self->numSbrElements; elementIndex++) for (elementIndex = 0; elementIndex < self->numSbrElements; elementIndex++) {
if (self->pSbrElement[elementIndex] != NULL)
{ {
HANDLE_SBR_HEADER_DATA hSbrHeader; HANDLE_SBR_HEADER_DATA hSbrHeader;
int headerIndex = getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot, int headerIndex = getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot,
...@@ -750,7 +773,7 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self, ...@@ -750,7 +773,7 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self,
This switches off bitstream parsing until a new header arrives. */ This switches off bitstream parsing until a new header arrives. */
hSbrHeader->syncState = UPSAMPLING; hSbrHeader->syncState = UPSAMPLING;
hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE; hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE;
} } }
} }
break; break;
default: default:
...@@ -767,7 +790,7 @@ SBRDEC_DRC_CHANNEL * sbrDecoder_drcGetChannel( const HANDLE_SBRDECODER self, con ...@@ -767,7 +790,7 @@ SBRDEC_DRC_CHANNEL * sbrDecoder_drcGetChannel( const HANDLE_SBRDECODER self, con
SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL; SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL;
int elementIndex, elChanIdx=0, numCh=0; int elementIndex, elChanIdx=0, numCh=0;
for (elementIndex = 0; (elementIndex < (4)) && (numCh <= channel); elementIndex++) for (elementIndex = 0; (elementIndex < (8)) && (numCh <= channel); elementIndex++)
{ {
SBR_DECODER_ELEMENT *pSbrElement = self->pSbrElement[elementIndex]; SBR_DECODER_ELEMENT *pSbrElement = self->pSbrElement[elementIndex];
int c, elChannels; int c, elChannels;
...@@ -829,7 +852,7 @@ SBR_ERROR sbrDecoder_drcFeedChannel ( HANDLE_SBRDECODER self, ...@@ -829,7 +852,7 @@ SBR_ERROR sbrDecoder_drcFeedChannel ( HANDLE_SBRDECODER self,
if (self == NULL) { if (self == NULL) {
return SBRDEC_NOT_INITIALIZED; return SBRDEC_NOT_INITIALIZED;
} }
if (ch > (6) || pNextFact_mag == NULL) { if (ch > (8) || pNextFact_mag == NULL) {
return SBRDEC_SET_PARAM_FAIL; return SBRDEC_SET_PARAM_FAIL;
} }
...@@ -874,7 +897,7 @@ void sbrDecoder_drcDisable ( HANDLE_SBRDECODER self, ...@@ -874,7 +897,7 @@ void sbrDecoder_drcDisable ( HANDLE_SBRDECODER self,
SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL; SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL;
if ( (self == NULL) if ( (self == NULL)
|| (ch > (6)) || (ch > (8))
|| (self->numSbrElements == 0) || (self->numSbrElements == 0)
|| (self->numSbrChannels == 0) ) { || (self->numSbrChannels == 0) ) {
return; return;
...@@ -1119,6 +1142,10 @@ SBR_ERROR sbrDecoder_Parse( ...@@ -1119,6 +1142,10 @@ SBR_ERROR sbrDecoder_Parse(
} }
} }
} }
} else {
/* The returned bit count will not be the actual payload size since we did not
parse the frame data. Return an error so that the caller can react respectively. */
errorStatus = SBRDEC_PARSE_ERROR;
} }
if (!fDoDecodeSbrData) { if (!fDoDecodeSbrData) {
...@@ -1198,6 +1225,15 @@ sbrDecoder_DecodeElement ( ...@@ -1198,6 +1225,15 @@ sbrDecoder_DecodeElement (
int stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0; int stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0;
int numElementChannels = hSbrElement->nChannels; /* Number of channels of the current SBR element */ int numElementChannels = hSbrElement->nChannels; /* Number of channels of the current SBR element */
if (self->flags & SBRDEC_FLUSH) {
/* Move frame pointer to the next slot which is up to be decoded/applied next */
hSbrElement->useFrameSlot = (hSbrElement->useFrameSlot+1) % (self->numDelayFrames+1);
/* Update header and frame data pointer because they have already been set */
hSbrHeader = &self->sbrHeader[elementIndex][hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]];
hFrameDataLeft = &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot];
hFrameDataRight = &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];
}
/* Update the header error flag */ /* Update the header error flag */
hSbrHeader->frameErrorFlag = hSbrElement->frameErrorFlag[hSbrElement->useFrameSlot]; hSbrHeader->frameErrorFlag = hSbrElement->frameErrorFlag[hSbrElement->useFrameSlot];
...@@ -1375,7 +1411,7 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self, ...@@ -1375,7 +1411,7 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self,
INT_PCM *timeData, INT_PCM *timeData,
int *numChannels, int *numChannels,
int *sampleRate, int *sampleRate,
const UCHAR channelMapping[(6)], const UCHAR channelMapping[(8)],
const int interleaved, const int interleaved,
const int coreDecodedOk, const int coreDecodedOk,
UCHAR *psDecoded ) UCHAR *psDecoded )
...@@ -1472,6 +1508,10 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self, ...@@ -1472,6 +1508,10 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self,
/* Clear reset and flush flag because everything seems to be done successfully. */
self->flags &= ~SBRDEC_FORCE_RESET;
self->flags &= ~SBRDEC_FLUSH;
bail: bail:
return errorStatus; return errorStatus;
...@@ -1496,7 +1536,7 @@ SBR_ERROR sbrDecoder_Close ( HANDLE_SBRDECODER *pSelf ) ...@@ -1496,7 +1536,7 @@ SBR_ERROR sbrDecoder_Close ( HANDLE_SBRDECODER *pSelf )
FreeRam_SbrDecWorkBuffer2(&self->workBuffer2); FreeRam_SbrDecWorkBuffer2(&self->workBuffer2);
} }
for (i = 0; i < (4); i++) { for (i = 0; i < (8); i++) {
sbrDecoder_DestroyElement( self, i ); sbrDecoder_DestroyElement( self, i );
} }
...@@ -1544,3 +1584,34 @@ INT sbrDecoder_GetLibInfo( LIB_INFO *info ) ...@@ -1544,3 +1584,34 @@ INT sbrDecoder_GetLibInfo( LIB_INFO *info )
return 0; return 0;
} }
UINT sbrDecoder_GetDelay( const HANDLE_SBRDECODER self )
{
UINT outputDelay = 0;
if ( self != NULL) {
UINT flags = self->flags;
/* See chapter 1.6.7.2 of ISO/IEC 14496-3 for the GA-SBR figures below. */
/* Are we initialized? */
if ( (self->numSbrChannels > 0)
&& (self->numSbrElements > 0) )
{
/* Add QMF synthesis delay */
if ( (flags & SBRDEC_ELD_GRID)
&& IS_LOWDELAY(self->coreCodec) ) {
/* Low delay SBR: */
{
outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 32 : 64; /* QMF synthesis */
}
}
else if (!IS_USAC(self->coreCodec)) {
/* By the method of elimination this is the GA (AAC-LC, HE-AAC, ...) branch: */
outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 481 : 962;
}
}
}
return (outputDelay);
}
...@@ -232,6 +232,14 @@ typedef enum ...@@ -232,6 +232,14 @@ typedef enum
} AUDIO_OBJECT_TYPE; } AUDIO_OBJECT_TYPE;
#define IS_USAC(aot) \
((aot) == AOT_USAC \
|| (aot) == AOT_RSVD50)
#define IS_LOWDELAY(aot) \
((aot) == AOT_ER_AAC_LD \
|| (aot) == AOT_ER_AAC_ELD)
/** Channel Mode ( 1-7 equals MPEG channel configurations, others are arbitrary). */ /** Channel Mode ( 1-7 equals MPEG channel configurations, others are arbitrary). */
typedef enum { typedef enum {
MODE_INVALID = -1, MODE_INVALID = -1,
...@@ -263,17 +271,29 @@ typedef enum { ...@@ -263,17 +271,29 @@ typedef enum {
} CHANNEL_MODE; } CHANNEL_MODE;
/** Speaker description tags */ /**
* Speaker description tags.
* Do not change the enumeration values unless it keeps the following segmentation:
* - Bit 0-3: Horizontal postion (0: none, 1: front, 2: side, 3: back, 4: lfe)
* - Bit 4-7: Vertical position (0: normal, 1: top, 2: bottom)
*/
typedef enum { typedef enum {
ACT_NONE, ACT_NONE = 0x00,
ACT_FRONT, ACT_FRONT = 0x01, /*!< Front speaker position (at normal height) */
ACT_SIDE, ACT_SIDE = 0x02, /*!< Side speaker position (at normal height) */
ACT_BACK, ACT_BACK = 0x03, /*!< Back speaker position (at normal height) */
ACT_LFE, ACT_LFE = 0x04, /*!< Low frequency effect speaker postion (front) */
ACT_FRONT_TOP,
ACT_SIDE_TOP, ACT_TOP = 0x10, /*!< Top speaker area (for combination with speaker positions) */
ACT_BACK_TOP, ACT_FRONT_TOP = 0x11, /*!< Top front speaker = (ACT_FRONT|ACT_TOP) */
ACT_TOP /* Ts */ ACT_SIDE_TOP = 0x12, /*!< Top side speaker = (ACT_SIDE |ACT_TOP) */
ACT_BACK_TOP = 0x13, /*!< Top back speaker = (ACT_BACK |ACT_TOP) */
ACT_BOTTOM = 0x20, /*!< Bottom speaker area (for combination with speaker positions) */
ACT_FRONT_BOTTOM = 0x21, /*!< Bottom front speaker = (ACT_FRONT|ACT_BOTTOM) */
ACT_SIDE_BOTTOM = 0x22, /*!< Bottom side speaker = (ACT_SIDE |ACT_BOTTOM) */
ACT_BACK_BOTTOM = 0x23 /*!< Bottom back speaker = (ACT_BACK |ACT_BOTTOM) */
} AUDIO_CHANNEL_TYPE; } AUDIO_CHANNEL_TYPE;
typedef enum typedef enum
......
...@@ -99,7 +99,7 @@ amm-info@iis.fraunhofer.de ...@@ -99,7 +99,7 @@ amm-info@iis.fraunhofer.de
/* library info */ /* library info */
#define SYS_LIB_VL0 1 #define SYS_LIB_VL0 1
#define SYS_LIB_VL1 3 #define SYS_LIB_VL1 3
#define SYS_LIB_VL2 4 #define SYS_LIB_VL2 6
#define SYS_LIB_TITLE "System Integration Library" #define SYS_LIB_TITLE "System Integration Library"
#define SYS_LIB_BUILD_DATE __DATE__ #define SYS_LIB_BUILD_DATE __DATE__
#define SYS_LIB_BUILD_TIME __TIME__ #define SYS_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