aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Storsjo <martin@martin.st>2016-08-25 22:12:15 +0300
committerMartin Storsjo <martin@martin.st>2016-08-25 22:12:15 +0300
commitf9d0f65e6578592149c01d8417197896283a821f (patch)
treeb6293c11023d196ed31b9c6ef765d645d872db49
parent15b128dd826ba86ee962d86b0b06966a25ed9158 (diff)
parent00fc1c66d5a524c6961db04d05e1076b18003231 (diff)
downloadfdk-aac-f9d0f65e6578592149c01d8417197896283a821f.tar.gz
fdk-aac-f9d0f65e6578592149c01d8417197896283a821f.tar.bz2
fdk-aac-f9d0f65e6578592149c01d8417197896283a821f.zip
Merge remote-tracking branch 'aosp/master'
-rw-r--r--documentation/aacDecoder.pdfbin505567 -> 387906 bytes
-rw-r--r--documentation/aacEncoder.pdfbin518665 -> 381677 bytes
-rw-r--r--libAACdec/include/aacdecoder_lib.h3
-rw-r--r--libAACdec/src/aac_rom.cpp85
-rw-r--r--libAACdec/src/aacdec_drc.cpp4
-rw-r--r--libAACdec/src/aacdecoder.cpp54
-rw-r--r--libAACdec/src/aacdecoder.h4
-rw-r--r--libAACdec/src/aacdecoder_lib.cpp45
-rw-r--r--libAACdec/src/block.cpp6
-rw-r--r--libAACenc/include/aacenc_lib.h23
-rw-r--r--libAACenc/src/aacEnc_rom.cpp32
-rw-r--r--libAACenc/src/aacEnc_rom.h14
-rw-r--r--libAACenc/src/aacenc.cpp89
-rw-r--r--libAACenc/src/aacenc.h39
-rw-r--r--libAACenc/src/aacenc_lib.cpp127
-rw-r--r--libAACenc/src/aacenc_tns.cpp102
-rw-r--r--libAACenc/src/aacenc_tns.h30
-rw-r--r--libAACenc/src/adj_thr.cpp97
-rw-r--r--libAACenc/src/adj_thr.h6
-rw-r--r--libAACenc/src/adj_thr_data.h3
-rw-r--r--libAACenc/src/bandwidth.cpp8
-rw-r--r--libAACenc/src/intensity.cpp2
-rw-r--r--libAACenc/src/pnsparam.cpp47
-rw-r--r--libAACenc/src/psy_configuration.cpp5
-rw-r--r--libAACenc/src/psy_main.cpp29
-rw-r--r--libAACenc/src/qc_data.h4
-rw-r--r--libAACenc/src/qc_main.cpp55
-rw-r--r--libAACenc/src/quantize.cpp24
-rw-r--r--libAACenc/src/quantize.h8
-rw-r--r--libAACenc/src/sf_estim.cpp73
-rw-r--r--libAACenc/src/sf_estim.h3
-rw-r--r--libAACenc/src/tns_func.h3
-rw-r--r--libFDK/include/fixpoint_math.h31
-rw-r--r--libFDK/src/FDK_core.cpp4
-rw-r--r--libFDK/src/FDK_tools_rom.cpp212
-rw-r--r--libFDK/src/arm/qmf_arm.cpp78
-rw-r--r--libMpegTPDec/src/tpdec_asc.cpp135
-rw-r--r--libMpegTPDec/src/tpdec_drm.cpp (renamed from libAACenc/src/aacenc_hcr.h)66
-rw-r--r--libMpegTPDec/src/tpdec_drm.h (renamed from libAACenc/src/aacenc_hcr.cpp)115
-rw-r--r--libMpegTPDec/src/tpdec_lib.cpp30
-rw-r--r--libMpegTPDec/src/version2
-rw-r--r--libMpegTPEnc/src/tpenc_latm.cpp27
-rw-r--r--libMpegTPEnc/src/version2
-rw-r--r--libSBRdec/include/sbrdecoder.h3
-rw-r--r--libSBRdec/src/env_calc.cpp204
-rw-r--r--libSBRdec/src/env_dec.cpp4
-rw-r--r--libSBRdec/src/env_extr.cpp4
-rw-r--r--libSBRdec/src/env_extr.h12
-rw-r--r--libSBRdec/src/sbr_dec.cpp62
-rw-r--r--libSBRdec/src/sbr_dec.h8
-rw-r--r--libSBRdec/src/sbr_ram.h3
-rw-r--r--libSBRdec/src/sbr_rom.cpp11
-rw-r--r--libSBRdec/src/sbr_rom.h3
-rw-r--r--libSBRdec/src/sbrdecoder.cpp181
-rw-r--r--libSBRenc/include/sbr_encoder.h19
-rw-r--r--libSBRenc/src/bit_sbr.cpp6
-rw-r--r--libSBRenc/src/bit_sbr.h8
-rw-r--r--libSBRenc/src/env_est.cpp175
-rw-r--r--libSBRenc/src/env_est.h3
-rw-r--r--libSBRenc/src/fram_gen.cpp82
-rw-r--r--libSBRenc/src/fram_gen.h30
-rw-r--r--libSBRenc/src/mh_det.cpp32
-rw-r--r--libSBRenc/src/nf_est.cpp9
-rw-r--r--libSBRenc/src/nf_est.h4
-rw-r--r--libSBRenc/src/ps_bitenc.cpp36
-rw-r--r--libSBRenc/src/ps_encode.cpp16
-rw-r--r--libSBRenc/src/sbr_def.h14
-rw-r--r--libSBRenc/src/sbr_encoder.cpp126
-rw-r--r--libSBRenc/src/sbr_rom.cpp11
-rw-r--r--libSBRenc/src/ton_corr.cpp8
-rw-r--r--libSBRenc/src/ton_corr.h4
-rw-r--r--libSBRenc/src/tran_det.cpp496
-rw-r--r--libSBRenc/src/tran_det.h61
-rw-r--r--libSYS/include/FDK_audio.h44
-rw-r--r--libSYS/src/genericStds.cpp4
75 files changed, 2591 insertions, 818 deletions
diff --git a/documentation/aacDecoder.pdf b/documentation/aacDecoder.pdf
index d388576..458fda1 100644
--- a/documentation/aacDecoder.pdf
+++ b/documentation/aacDecoder.pdf
Binary files differ
diff --git a/documentation/aacEncoder.pdf b/documentation/aacEncoder.pdf
index e8420b1..efb1858 100644
--- a/documentation/aacEncoder.pdf
+++ b/documentation/aacEncoder.pdf
Binary files differ
diff --git a/libAACdec/include/aacdecoder_lib.h b/libAACdec/include/aacdecoder_lib.h
index 1e90777..44e2c1f 100644
--- a/libAACdec/include/aacdecoder_lib.h
+++ b/libAACdec/include/aacdecoder_lib.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -382,6 +382,7 @@ typedef enum {
not exist. */
AAC_DEC_NEED_TO_RESTART = 0x200B, /*!< The decoder needs to be restarted, since the requiered configuration change cannot be
performed. */
+ AAC_DEC_OUTPUT_BUFFER_TOO_SMALL = 0x200C, /*!< The provided output buffer is too small. */
aac_dec_init_error_end = 0x2FFF,
/* Decode errors. Output buffer is valid but concealed. */
diff --git a/libAACdec/src/aac_rom.cpp b/libAACdec/src/aac_rom.cpp
index 607cb3b..f3c9b5a 100644
--- a/libAACdec/src/aac_rom.cpp
+++ b/libAACdec/src/aac_rom.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -167,6 +167,36 @@ const SCHAR ExponentTable [4][14] =
} ;
+/* 41 scfbands */
+static const SHORT sfb_96_1024[42] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44,
+ 48, 52, 56, 64, 72, 80, 88, 96, 108, 120, 132, 144,
+ 156, 172, 188, 212, 240, 276, 320, 384, 448, 512, 576, 640,
+ 704, 768, 832, 896, 960, 1024
+};
+/* 12 scfbands */
+static const SHORT sfb_96_128[13] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92,
+ 128
+};
+
+/* 47 scfbands*/
+static const SHORT sfb_64_1024[48] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52,
+ 56, 64, 72, 80, 88, 100, 112, 124, 140, 156, 172, 192, 216, 240,
+ 268, 304, 344, 384, 424, 464, 504, 544, 584, 624, 664, 704, 744, 784,
+ 824, 864, 904, 944, 984,1024
+};
+
+/* 12 scfbands */
+static const SHORT sfb_64_128[13] =
+{
+ 0, 4, 8, 12, 16, 20, 24,
+ 32, 40, 48, 64, 92, 128
+};
/* 49 scfbands */
static const SHORT sfb_48_1024[50] = {
@@ -239,6 +269,35 @@ static const SHORT sfb_8_128[16] =
};
+static const SHORT sfb_96_960[42] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+ 40, 44, 48, 52, 56, 64, 72, 80, 88, 96,
+ 108, 120, 132, 144, 156, 172, 188, 212, 240, 276,
+ 320, 384, 448, 512, 576, 640, 704, 768, 832, 896,
+ 960
+}; /* 40 scfbands */
+
+static const SHORT sfb_96_120[13] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 32, 40, 48,
+ 64, 92, 120
+}; /* 12 scfbands */
+
+static const SHORT sfb_64_960[47] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+ 40, 44, 48, 52, 56, 64, 72, 80, 88, 100,
+ 112, 124, 140, 156, 172, 192, 216, 240, 268, 304,
+ 344, 384, 424, 464, 504, 544, 584, 624, 664, 704,
+ 744, 784, 824, 864, 904, 944, 960
+}; /* 46 scfbands */
+
+static const SHORT sfb_64_120[13] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 32, 40, 48,
+ 64, 92, 120
+}; /* 12 scfbands */
static const SHORT sfb_48_960[50] =
{
@@ -358,9 +417,9 @@ static const SHORT sfb_24_480[31] =
const SFB_INFO sfbOffsetTables[5][16] =
{
{
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
+ { sfb_96_1024, sfb_96_128, 41, 12 },
+ { sfb_96_1024, sfb_96_128, 41, 12 },
+ { sfb_64_1024, sfb_64_128, 47, 12 },
{ sfb_48_1024, sfb_48_128, 49, 14 },
{ sfb_48_1024, sfb_48_128, 49, 14 },
{ sfb_32_1024, sfb_48_128, 51, 14 },
@@ -372,9 +431,9 @@ const SFB_INFO sfbOffsetTables[5][16] =
{ sfb_8_1024, sfb_8_128, 40, 15 },
{ sfb_8_1024, sfb_8_128, 40, 15 },
}, {
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
+ { sfb_96_960, sfb_96_120, 40, 12 },
+ { sfb_96_960, sfb_96_120, 40, 12 },
+ { sfb_64_960, sfb_64_120, 46, 12 },
{ sfb_48_960, sfb_48_120, 49, 14 },
{ sfb_48_960, sfb_48_120, 49, 14 },
{ sfb_32_960, sfb_48_120, 49, 14 },
@@ -388,9 +447,9 @@ const SFB_INFO sfbOffsetTables[5][16] =
}, {
{ NULL, NULL, 0, 0 },
}, {
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
+ { sfb_48_512, NULL, 36, 0 },
+ { sfb_48_512, NULL, 36, 0 },
+ { sfb_48_512, NULL, 36, 0 },
{ sfb_48_512, NULL, 36, 0 },
{ sfb_48_512, NULL, 36, 0},
{ sfb_32_512, NULL, 37, 0 },
@@ -402,9 +461,9 @@ const SFB_INFO sfbOffsetTables[5][16] =
{ sfb_24_512, NULL, 31, 0 },
{ sfb_24_512, NULL, 31, 0 },
}, {
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
+ { sfb_48_480, NULL, 35, 0 },
+ { sfb_48_480, NULL, 35, 0 },
+ { sfb_48_480, NULL, 35, 0 },
{ sfb_48_480, NULL, 35, 0 },
{ sfb_48_480, NULL, 35, 0 },
{ sfb_32_480, NULL, 37, 0 },
diff --git a/libAACdec/src/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp
index 0c33a2b..eb8e410 100644
--- a/libAACdec/src/aacdec_drc.cpp
+++ b/libAACdec/src/aacdec_drc.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -705,7 +705,7 @@ static int aacDecoder_drcExtractAndMap (
}
self->numPayloads = 0;
- if (self->dvbAncDataAvailable)
+ if (self->dvbAncDataAvailable && self->numThreads < MAX_DRC_THREADS)
{ /* Append a DVB heavy compression payload thread if available. */
int bitsParsed;
diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp
index e19c501..579e470 100644
--- a/libAACdec/src/aacdecoder.cpp
+++ b/libAACdec/src/aacdecoder.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -157,23 +157,9 @@ amm-info@iis.fraunhofer.de
#include "conceal.h"
+ #include "FDK_crc.h"
-#define CAN_DO_PS(aot) \
- ((aot) == AOT_AAC_LC \
-|| (aot) == AOT_SBR \
-|| (aot) == AOT_PS \
-|| (aot) == AOT_ER_BSAC \
-|| (aot) == AOT_DRM_AAC)
-
-#define IS_USAC(aot) \
- ((aot) == AOT_USAC \
-|| (aot) == AOT_RSVD50)
-
-#define IS_LOWDELAY(aot) \
- ((aot) == AOT_ER_AAC_LD \
-|| (aot) == AOT_ER_AAC_ELD)
-
void CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self)
{
@@ -552,8 +538,9 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
previous_element,
elIndex,
self->flags & AC_INDEP );
- /* Enable SBR for implicit SBR signalling. */
- if (sbrError == SBRDEC_OK) {
+ /* Enable SBR for implicit SBR signalling but only if no severe error happend. */
+ if ( (sbrError == SBRDEC_OK)
+ || (sbrError == SBRDEC_PARSE_ERROR) ) {
self->sbrEnabled = 1;
}
} else {
@@ -568,7 +555,7 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
FDKpushBiDirectional(hBs, *count);
*count = 0;
} else {
- /* If this is not a fill element with a known length, we are screwed an no further parsing makes sense. */
+ /* If this is not a fill element with a known length, we are screwed and further parsing makes no sense. */
if (sbrError != SBRDEC_OK) {
self->frameOK = 0;
}
@@ -847,12 +834,18 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
switch (asc->m_aot) {
case AOT_AAC_LC:
self->streamInfo.profile = 1;
- break;
+
+ case AOT_ER_AAC_SCAL:
+ if (asc->m_sc.m_gaSpecificConfig.m_layer > 0) {
+ /* aac_scalable_extension_element() currently not supported. */
+ return AAC_DEC_UNSUPPORTED_FORMAT;
+ }
case AOT_SBR:
case AOT_PS:
case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD:
+ case AOT_DRM_AAC:
break;
default:
@@ -972,11 +965,20 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
if (asc->m_aot == AOT_ER_AAC_ELD) {
self->flags |= AC_ELD;
+ self->flags |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0; /* Need to set the SBR flag for backward-compatibility
+ reasons. Even if SBR is not supported. */
self->flags |= (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0;
self->flags |= (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) ? AC_LD_MPS : 0;
}
self->flags |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0;
self->flags |= (asc->m_epConfig >= 0) ? AC_ER : 0;
+ if ( asc->m_aot == AOT_DRM_AAC ) {
+ self->flags |= AC_DRM|AC_SBRCRC|AC_SCALABLE;
+ }
+ if ( (asc->m_aot == AOT_AAC_SCAL)
+ || (asc->m_aot == AOT_ER_AAC_SCAL) ) {
+ self->flags |= AC_SCALABLE;
+ }
if (asc->m_sbrPresentFlag) {
@@ -1162,6 +1164,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
/* Check sampling frequency */
switch ( self->streamInfo.aacSampleRate ) {
+ case 96000:
+ case 88200:
+ case 64000:
case 16000:
case 12000:
case 11025:
@@ -1490,7 +1495,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
/* get the remaining bits of this frame */
bitCnt = transportDec_GetAuBitsRemaining(self->hInput, 0);
- if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD)) )
+ if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD|AC_DRM)) )
{
SBR_ERROR err = SBRDEC_OK;
int elIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE];
@@ -1528,6 +1533,13 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
}
+ if (self->flags & AC_DRM)
+ {
+ if ((bitCnt = (INT)FDKgetValidBits(bs)) != 0) {
+ FDKpushBiDirectional(bs, bitCnt);
+ }
+ }
+
if ( ! (self->flags & (AC_USAC|AC_RSVD50|AC_DRM)) )
{
while ( bitCnt > 7 ) {
diff --git a/libAACdec/src/aacdecoder.h b/libAACdec/src/aacdecoder.h
index 3541773..25bc35d 100644
--- a/libAACdec/src/aacdecoder.h
+++ b/libAACdec/src/aacdecoder.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -226,6 +226,8 @@ struct AAC_DECODER_INSTANCE {
FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */
UINT extGainDelay; /*!< Delay that must be accounted for extGain. */
+ INT_PCM pcmOutputBuffer[(8)*(2048)];
+
};
diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp
index 94eb3c0..8863da5 100644
--- a/libAACdec/src/aacdecoder_lib.cpp
+++ b/libAACdec/src/aacdecoder_lib.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -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 10
+#define AACDECODER_LIB_VL2 17
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
#ifdef __ANDROID__
#define AACDECODER_LIB_BUILD_DATE ""
@@ -181,8 +181,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_ConfigRaw (
break;
}
/* if baselayer is OK we continue decoding */
- if(layer >= 1){
+ if(layer >= 1){
self->nrOfLayers = layer;
+ err = AAC_DEC_OK;
}
break;
}
@@ -785,8 +786,8 @@ static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self)
LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
HANDLE_AACDECODER self,
- INT_PCM *pTimeData,
- const INT timeDataSize,
+ INT_PCM *pTimeData_extern,
+ const INT timeDataSize_extern,
const UINT flags)
{
AAC_DECODER_ERROR ErrorStatus;
@@ -796,12 +797,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
HANDLE_FDK_BITSTREAM hBs;
int fTpInterruption = 0; /* Transport originated interruption detection. */
int fTpConceal = 0; /* Transport originated concealment. */
+ INT_PCM *pTimeData = NULL;
+ INT timeDataSize = 0;
if (self == NULL) {
return AAC_DEC_INVALID_HANDLE;
}
+ pTimeData = self->pcmOutputBuffer;
+ timeDataSize = sizeof(self->pcmOutputBuffer)/sizeof(*self->pcmOutputBuffer);
+
if (flags & AACDEC_INTR) {
self->streamInfo.numLostAccessUnits = 0;
}
@@ -918,7 +924,8 @@ 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;
+ int chIdx, numCoreChannel = self->streamInfo.numChannels;
+ int chOutMapIdx = ((self->chMapIndex==0) && (numCoreChannel<7)) ? numCoreChannel : self->chMapIndex;
/* set params */
sbrDecoder_SetParam ( self->hSbrDecoder,
@@ -978,10 +985,10 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
if (self->psPossible) {
self->flags |= AC_PS_PRESENT;
- self->channelType[0] = ACT_FRONT;
- self->channelType[1] = ACT_FRONT;
- self->channelIndices[0] = 0;
- self->channelIndices[1] = 1;
+ }
+ for (chIdx = numCoreChannel; chIdx < self->streamInfo.numChannels; chIdx+=1) {
+ self->channelType[chIdx] = ACT_FRONT;
+ self->channelIndices[chIdx] = chIdx;
}
}
}
@@ -1006,7 +1013,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
self->channelOutputMapping,
(self->limiterEnableCurr) ? &pcmLimiterScale : NULL
);
- if (dmxErr == PCMDMX_INVALID_MODE) {
+ if ( (ErrorStatus == AAC_DEC_OK)
+ && (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;
@@ -1051,6 +1059,19 @@ bail:
/* Update Statistics */
aacDecoder_UpdateBitStreamCounters(&self->streamInfo, hBs, nBits, ErrorStatus);
+ /* Check whether external output buffer is large enough. */
+ if (timeDataSize_extern < self->streamInfo.numChannels*self->streamInfo.frameSize) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ }
+
+ /* Update external output buffer. */
+ if ( IS_OUTPUT_VALID(ErrorStatus) ) {
+ FDKmemcpy(pTimeData_extern, pTimeData, self->streamInfo.numChannels*self->streamInfo.frameSize*sizeof(*pTimeData));
+ }
+ else {
+ FDKmemclear(pTimeData_extern, timeDataSize_extern*sizeof(*pTimeData_extern));
+ }
+
return ErrorStatus;
}
@@ -1120,6 +1141,7 @@ LINKSPEC_CPP INT aacDecoder_GetLibInfo ( LIB_INFO *info )
/* Set flags */
info->flags = 0
| CAPF_AAC_LC
+ | CAPF_ER_AAC_SCAL
| CAPF_AAC_VCB11
| CAPF_AAC_HCR
| CAPF_AAC_RVLC
@@ -1130,6 +1152,7 @@ LINKSPEC_CPP INT aacDecoder_GetLibInfo ( LIB_INFO *info )
| CAPF_AAC_MPEG4
+ | CAPF_AAC_DRM_BSFORMAT
| CAPF_AAC_1024
| CAPF_AAC_960
diff --git a/libAACdec/src/block.cpp b/libAACdec/src/block.cpp
index 526accb..a19284e 100644
--- a/libAACdec/src/block.cpp
+++ b/libAACdec/src/block.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -324,11 +324,11 @@ AAC_DECODER_ERROR CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs,
if (flags & AC_ER_HCR) {
/* HCR input (long) -- collecting sideinfo (for HCR-_long_ only) */
- pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
- numLinesInSecIdx++;
if (numLinesInSecIdx >= MAX_SFB_HCR) {
return AAC_DEC_PARSE_ERROR;
}
+ pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
+ numLinesInSecIdx++;
if (sect_cb == BOOKSCL)
{
return AAC_DEC_INVALID_CODE_BOOK;
diff --git a/libAACenc/include/aacenc_lib.h b/libAACenc/include/aacenc_lib.h
index 307dfd4..65a77f7 100644
--- a/libAACenc/include/aacenc_lib.h
+++ b/libAACenc/include/aacenc_lib.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -900,11 +900,7 @@ typedef enum
This configuration can be used only with stereo input audio data.
- 23: MPEG-4 AAC Low-Delay.
- 39: MPEG-4 AAC Enhanced Low-Delay. Since there is no ::AUDIO_OBJECT_TYPE for ELD in
- combination with SBR defined, enable SBR explicitely by ::AACENC_SBR_MODE parameter.
- - 129: MPEG-2 AAC Low Complexity.
- - 132: MPEG-2 AAC Low Complexity with Spectral Band Replication (HE-AAC).
- - 156: MPEG-2 AAC Low Complexity with Spectral Band Replication and Parametric Stereo (HE-AAC v2).
- This configuration can be used only with stereo input audio data. */
+ combination with SBR defined, enable SBR explicitely by ::AACENC_SBR_MODE parameter. */
AACENC_BITRATE = 0x0101, /*!< Total encoder bitrate. This parameter is mandatory and interacts with ::AACENC_BITRATEMODE.
- CBR: Bitrate in bits/second.
@@ -961,6 +957,16 @@ typedef enum
- 1 to fs/2: Frequency bandwidth in Hertz. (Experts only, better do not
touch this value to avoid degraded audio quality) */
+ AACENC_PEAK_BITRATE = 0x0207, /*!< Peak bitrate configuration parameter to adjust maximum bits per audio frame. Bitrate is in bits/second.
+ The peak bitrate will internally be limited to the chosen bitrate ::AACENC_BITRATE as lower limit
+ and the number_of_effective_channels*6144 bit as upper limit.
+
+ Setting the peak bitrate equal to ::AACENC_BITRATE does not necessarily mean that the audio frames
+ will be of constant size. Since the peak bitate is in bits/second, the frame sizes can vary by
+ one byte in one or the other direction over various frames. However, it is not recommended to reduce
+ the peak pitrate to ::AACENC_BITRATE - it would disable the bitreservoir, which would affect the
+ audio quality by a large amount. */
+
AACENC_TRANSMUX = 0x0300, /*!< Transport type to be used. See ::TRANSPORT_TYPE in FDK_audio.h. Following
types can be configured in encoder library:
- 0: raw access units
@@ -1026,6 +1032,11 @@ typedef enum
- ADTS: Maximum number of sub frames restricted to 4.
- LOAS/LATM: Maximum number of sub frames restricted to 2.*/
+ AACENC_AUDIOMUXVER = 0x0304, /*!< AudioMuxVersion to be used for LATM. (AudioMuxVersionA, currently not implemented):
+ - 0: Default, no transmission of tara Buffer fullness, no ASC length and including actual latm Buffer fullnes.
+ - 1: Transmission of tara Buffer fullness, ASC length and actual latm Buffer fullness.
+ - 2: Transmission of tara Buffer fullness, ASC length and maximum level of latm Buffer fullness. */
+
AACENC_PROTECTION = 0x0306, /*!< Configure protection in tranpsort layer:
- 0: No protection. (default)
- 1: CRC active for ADTS bitstream format. */
diff --git a/libAACenc/src/aacEnc_rom.cpp b/libAACenc/src/aacEnc_rom.cpp
index 0cdf5fe..c6477e3 100644
--- a/libAACenc/src/aacEnc_rom.cpp
+++ b/libAACenc/src/aacEnc_rom.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -93,7 +93,7 @@ amm-info@iis.fraunhofer.de
/*
Huffman Tables
*/
-const INT FDKaacEnc_huff_ltab1_2[3][3][3][3]=
+const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3]=
{
{
{ {0x000b0009,0x00090007,0x000b0009}, {0x000a0008,0x00070006,0x000a0008}, {0x000b0009,0x00090008,0x000b0009} },
@@ -113,7 +113,7 @@ const INT FDKaacEnc_huff_ltab1_2[3][3][3][3]=
};
-const INT FDKaacEnc_huff_ltab3_4[3][3][3][3]=
+const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3]=
{
{
{ {0x00010004,0x00040005,0x00080008}, {0x00040005,0x00050004,0x00080008}, {0x00090009,0x00090008,0x000a000b} },
@@ -132,7 +132,7 @@ const INT FDKaacEnc_huff_ltab3_4[3][3][3][3]=
}
};
-const INT FDKaacEnc_huff_ltab5_6[9][9]=
+const ULONG FDKaacEnc_huff_ltab5_6[9][9]=
{
{0x000d000b, 0x000c000a, 0x000b0009, 0x000b0009, 0x000a0009, 0x000b0009, 0x000b0009, 0x000c000a, 0x000d000b},
{0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007, 0x000a0008, 0x000b0009, 0x000c000a},
@@ -145,7 +145,7 @@ const INT FDKaacEnc_huff_ltab5_6[9][9]=
{0x000d000b, 0x000c000a, 0x000c0009, 0x000b0009, 0x000a0009, 0x000a0009, 0x000b0009, 0x000c000a, 0x000d000b}
};
-const INT FDKaacEnc_huff_ltab7_8[8][8]=
+const ULONG FDKaacEnc_huff_ltab7_8[8][8]=
{
{0x00010005, 0x00030004, 0x00060005, 0x00070006, 0x00080007, 0x00090008, 0x000a0009, 0x000b000a},
{0x00030004, 0x00040003, 0x00060004, 0x00070005, 0x00080006, 0x00080007, 0x00090007, 0x00090008},
@@ -157,7 +157,7 @@ const INT FDKaacEnc_huff_ltab7_8[8][8]=
{0x000b000a, 0x000a0008, 0x000a0008, 0x000a0008, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c000a}
};
-const INT FDKaacEnc_huff_ltab9_10[13][13]=
+const ULONG FDKaacEnc_huff_ltab9_10[13][13]=
{
{0x00010006, 0x00030005, 0x00060006, 0x00080006, 0x00090007, 0x000a0008, 0x000a0009, 0x000b000a, 0x000b000a, 0x000c000a, 0x000c000b, 0x000d000b, 0x000d000c},
{0x00030005, 0x00040004, 0x00060004, 0x00070005, 0x00080006, 0x00080007, 0x00090007, 0x000a0008, 0x000a0008, 0x000a0009, 0x000b000a, 0x000c000a, 0x000c000b},
@@ -392,7 +392,7 @@ const USHORT FDKaacEnc_huff_ctab11[21][17]=
{0x0046, 0x00ea, 0x0034, 0x00ea, 0x0011, 0x001b, 0x00a9, 0x0094, 0x00e2, 0x0031, 0x00d0, 0x00e5, 0x0007, 0x0070, 0x0069, 0x003e, 0x0021}
};
-const INT FDKaacEnc_huff_ctabscf[121]=
+const ULONG FDKaacEnc_huff_ctabscf[121]=
{
0x0003ffe8, 0x0003ffe6, 0x0003ffe7, 0x0003ffe5, 0x0007fff5, 0x0007fff1, 0x0007ffed, 0x0007fff6,
0x0007ffee, 0x0007ffef, 0x0007fff0, 0x0007fffc, 0x0007fffd, 0x0007ffff, 0x0007fffe, 0x0007fff7,
@@ -657,11 +657,11 @@ const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_128 = {
*/
const FIXP_DBL FDKaacEnc_tnsEncCoeff3[8]=
{
- 0x81f1d201, 0x91261481, 0xadb92301, 0xd438af00, 0x00000000, 0x37898080, 0x64130dff, 0x7cca6fff
+ (FIXP_DBL)0x81f1d201, (FIXP_DBL)0x91261481, (FIXP_DBL)0xadb92301, (FIXP_DBL)0xd438af00, (FIXP_DBL)0x00000000, (FIXP_DBL)0x37898080, (FIXP_DBL)0x64130dff, (FIXP_DBL)0x7cca6fff
};
const FIXP_DBL FDKaacEnc_tnsCoeff3Borders[8]={
- 0x80000001 /*-4*/, 0x87b826df /*-3*/, 0x9df24154 /*-2*/, 0xbfffffe5 /*-1*/,
- 0xe9c5e578 /* 0*/, 0x1c7b90f0 /* 1*/, 0x4fce83a9 /* 2*/, 0x7352f2c3 /* 3*/
+ (FIXP_DBL)0x80000001 /*-4*/, (FIXP_DBL)0x87b826df /*-3*/, (FIXP_DBL)0x9df24154 /*-2*/, (FIXP_DBL)0xbfffffe5 /*-1*/,
+ (FIXP_DBL)0xe9c5e578 /* 0*/, (FIXP_DBL)0x1c7b90f0 /* 1*/, (FIXP_DBL)0x4fce83a9 /* 2*/, (FIXP_DBL)0x7352f2c3 /* 3*/
};
/*
@@ -669,15 +669,15 @@ const FIXP_DBL FDKaacEnc_tnsCoeff3Borders[8]={
*/
const FIXP_DBL FDKaacEnc_tnsEncCoeff4[16]=
{
- 0x808bc881, 0x84e2e581, 0x8d6b4a01, 0x99da9201, 0xa9c45701, 0xbc9dde81, 0xd1c2d500, 0xe87ae540,
- 0x00000000, 0x1a9cd9c0, 0x340ff240, 0x4b3c8bff, 0x5f1f5e7f, 0x6ed9eb7f, 0x79bc387f, 0x7f4c7e7f
+ (FIXP_DBL)0x808bc881, (FIXP_DBL)0x84e2e581, (FIXP_DBL)0x8d6b4a01, (FIXP_DBL)0x99da9201, (FIXP_DBL)0xa9c45701, (FIXP_DBL)0xbc9dde81, (FIXP_DBL)0xd1c2d500, (FIXP_DBL)0xe87ae540,
+ (FIXP_DBL)0x00000000, (FIXP_DBL)0x1a9cd9c0, (FIXP_DBL)0x340ff240, (FIXP_DBL)0x4b3c8bff, (FIXP_DBL)0x5f1f5e7f, (FIXP_DBL)0x6ed9eb7f, (FIXP_DBL)0x79bc387f, (FIXP_DBL)0x7f4c7e7f
};
const FIXP_DBL FDKaacEnc_tnsCoeff4Borders[16]=
{
- 0x80000001 /*-8*/, 0x822deff0 /*-7*/, 0x88a4bfe6 /*-6*/, 0x932c159d /*-5*/,
- 0xa16827c2 /*-4*/, 0xb2dcde27 /*-3*/, 0xc6f20b91 /*-2*/, 0xdcf89c64 /*-1*/,
- 0xf4308ce1 /* 0*/, 0x0d613054 /* 1*/, 0x278dde80 /* 2*/, 0x4000001b /* 3*/,
- 0x55a6127b /* 4*/, 0x678dde8f /* 5*/, 0x74ef0ed7 /* 6*/, 0x7d33f0da /* 7*/
+ (FIXP_DBL)0x80000001 /*-8*/, (FIXP_DBL)0x822deff0 /*-7*/, (FIXP_DBL)0x88a4bfe6 /*-6*/, (FIXP_DBL)0x932c159d /*-5*/,
+ (FIXP_DBL)0xa16827c2 /*-4*/, (FIXP_DBL)0xb2dcde27 /*-3*/, (FIXP_DBL)0xc6f20b91 /*-2*/, (FIXP_DBL)0xdcf89c64 /*-1*/,
+ (FIXP_DBL)0xf4308ce1 /* 0*/, (FIXP_DBL)0x0d613054 /* 1*/, (FIXP_DBL)0x278dde80 /* 2*/, (FIXP_DBL)0x4000001b /* 3*/,
+ (FIXP_DBL)0x55a6127b /* 4*/, (FIXP_DBL)0x678dde8f /* 5*/, (FIXP_DBL)0x74ef0ed7 /* 6*/, (FIXP_DBL)0x7d33f0da /* 7*/
};
const FIXP_DBL FDKaacEnc_mTab_4_3Elc[512]={
FL2FXCONST_DBL(0.3968502629920499),FL2FXCONST_DBL(0.3978840634868335),FL2FXCONST_DBL(0.3989185359354711),FL2FXCONST_DBL(0.3999536794661432),
diff --git a/libAACenc/src/aacEnc_rom.h b/libAACenc/src/aacEnc_rom.h
index 37e5012..862417f 100644
--- a/libAACenc/src/aacEnc_rom.h
+++ b/libAACenc/src/aacEnc_rom.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -105,11 +105,11 @@ amm-info@iis.fraunhofer.de
/*
Huffman Tables
*/
-extern const INT FDKaacEnc_huff_ltab1_2[3][3][3][3];
-extern const INT FDKaacEnc_huff_ltab3_4[3][3][3][3];
-extern const INT FDKaacEnc_huff_ltab5_6[9][9];
-extern const INT FDKaacEnc_huff_ltab7_8[8][8];
-extern const INT FDKaacEnc_huff_ltab9_10[13][13];
+extern const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3];
+extern const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3];
+extern const ULONG FDKaacEnc_huff_ltab5_6[9][9];
+extern const ULONG FDKaacEnc_huff_ltab7_8[8][8];
+extern const ULONG FDKaacEnc_huff_ltab9_10[13][13];
extern const UCHAR FDKaacEnc_huff_ltab11[17][17];
extern const UCHAR FDKaacEnc_huff_ltabscf[121];
extern const USHORT FDKaacEnc_huff_ctab1[3][3][3][3];
@@ -123,7 +123,7 @@ extern const USHORT FDKaacEnc_huff_ctab8[8][8];
extern const USHORT FDKaacEnc_huff_ctab9[13][13];
extern const USHORT FDKaacEnc_huff_ctab10[13][13];
extern const USHORT FDKaacEnc_huff_ctab11[21][17];
-extern const INT FDKaacEnc_huff_ctabscf[121];
+extern const ULONG FDKaacEnc_huff_ctabscf[121];
/*
quantizer
diff --git a/libAACenc/src/aacenc.cpp b/libAACenc/src/aacenc.cpp
index 569662b..5e8c08d 100644
--- a/libAACenc/src/aacenc.cpp
+++ b/libAACenc/src/aacenc.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -107,6 +107,39 @@ amm-info@iis.fraunhofer.de
#define MIN_BUFSIZE_PER_EFF_CHAN 6144
+INT FDKaacEnc_CalcBitsPerFrame(
+ const INT bitRate,
+ const INT frameLength,
+ const INT samplingRate
+ )
+{
+ int shift = 0;
+ while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength
+ && (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate)
+ {
+ shift++;
+ }
+
+ return (bitRate*(frameLength>>shift)) / (samplingRate>>shift);
+}
+
+INT FDKaacEnc_CalcBitrate(
+ const INT bitsPerFrame,
+ const INT frameLength,
+ const INT samplingRate
+ )
+{
+ int shift = 0;
+ while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength
+ && (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate)
+ {
+ shift++;
+ }
+
+ return (bitsPerFrame * (samplingRate>>shift)) / ( frameLength>>shift) ;
+
+}
+
static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(INT bitRate,
INT framelength,
INT ancillaryRate,
@@ -220,21 +253,19 @@ INT FDKaacEnc_GetVBRBitrate(INT bitrateMode, CHANNEL_MODE channelMode)
/**
* \brief Convert encoder bitreservoir value for transport library.
*
- * \param bitrateMode Bitratemode used in current encoder instance. Se ::AACENC_BITRATE_MODE
- * \param bitresTotal Encoder bitreservoir level in bits.
+ * \param hAacEnc Encoder handle
*
* \return Corrected bitreservoir level used in transport library.
*/
static INT FDKaacEnc_EncBitresToTpBitres(
- const AACENC_BITRATE_MODE bitrateMode,
- const INT bitresTotal
+ const HANDLE_AAC_ENC hAacEnc
)
{
INT transporBitreservoir = 0;
- switch (bitrateMode) {
+ switch (hAacEnc->bitrateMode) {
case AACENC_BR_MODE_CBR:
- transporBitreservoir = bitresTotal; /* encoder bitreservoir level */
+ transporBitreservoir = hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */
break;
case AACENC_BR_MODE_VBR_1:
case AACENC_BR_MODE_VBR_2:
@@ -253,6 +284,10 @@ static INT FDKaacEnc_EncBitresToTpBitres(
FDK_ASSERT(0);
}
+ if (hAacEnc->config->audioMuxVersion==2) {
+ transporBitreservoir = MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff;
+ }
+
return transporBitreservoir;
}
@@ -289,6 +324,7 @@ void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config)
config->minBitsPerFrame = -1; /* minum number of bits in each AU */
config->maxBitsPerFrame = -1; /* minum number of bits in each AU */
config->bitreservoir = -1; /* default, uninitialized value */
+ config->audioMuxVersion = -1; /* audio mux version not configured */
/* init tabs in fixpoint_math */
InitLdInt();
@@ -435,7 +471,9 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,
&averageBitsPerFrame,
config->bitrateMode,
config->nSubFrames
- ) != config->bitRate )
+ ) != config->bitRate
+ && !((config->bitrateMode>=1) && (config->bitrateMode<=5))
+ )
{
return AAC_ENC_UNSUPPORTED_BITRATE;
}
@@ -562,7 +600,10 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,
qcInit.averageBits = (averageBitsPerFrame+7)&~7;
qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff;
qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff;
- qcInit.minBits = 0;
+ qcInit.maxBits = (config->maxBitsPerFrame!=-1) ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) : qcInit.maxBits;
+ qcInit.maxBits = fixMax(qcInit.maxBits, (averageBitsPerFrame+7)&~7);
+ qcInit.minBits = (config->minBitsPerFrame!=-1) ? config->minBitsPerFrame : 0;
+ qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame&~7);
}
else
{
@@ -573,9 +614,11 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,
qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes);
qcInit.maxBits = (config->maxBitsPerFrame!=-1) ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) : qcInit.maxBits;
+ qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff, fixMax(qcInit.maxBits, (averageBitsPerFrame+7+8)&~7));
qcInit.minBits = fixMax(0, ((averageBitsPerFrame-1)&~7)-qcInit.bitRes-transportEnc_GetStaticBits(hTpEnc, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes));
qcInit.minBits = (config->minBitsPerFrame!=-1) ? fixMax(qcInit.minBits, config->minBitsPerFrame) : qcInit.minBits;
+ qcInit.minBits = fixMin(qcInit.minBits, (averageBitsPerFrame - transportEnc_GetStaticBits(hTpEnc, qcInit.maxBits))&~7);
}
qcInit.sampleRate = config->sampleRate;
@@ -583,11 +626,9 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,
qcInit.nSubFrames = config->nSubFrames;
qcInit.padding.paddingRest = config->sampleRate;
- /* Calc meanPe */
- bw_ratio = fDivNorm((FIXP_DBL)hAacEnc->bandwidth90dB, (FIXP_DBL)(config->sampleRate>>1), &qbw);
- qbw = DFRACT_BITS-1-qbw;
- /* qcInit.meanPe = 10.0f * FRAME_LEN_LONG * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */
- qcInit.meanPe = fMult(bw_ratio, (FIXP_DBL)((10*config->framelength)<<16)) >> (qbw-15);
+ /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */
+ bw_ratio = fDivNorm((FIXP_DBL)(10*config->framelength*hAacEnc->bandwidth90dB), (FIXP_DBL)(config->sampleRate), &qbw);
+ qcInit.meanPe = FDKmax((INT)scaleValue(bw_ratio, qbw+1-(DFRACT_BITS-1)), 1);
/* Calc maxBitFac */
mbfac = fDivNorm((MIN_BUFSIZE_PER_EFF_CHAN-744)*cm->nChannelsEff, qcInit.averageBits/qcInit.nSubFrames, &qmbfac);
@@ -649,23 +690,7 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,
if (ErrorStatus != AAC_ENC_OK)
goto bail;
- /* Map virtual aot's to intern aot used in bitstream writer. */
- switch (hAacEnc->config->audioObjectType) {
- case AOT_MP2_AAC_LC:
- case AOT_DABPLUS_AAC_LC:
- hAacEnc->aot = AOT_AAC_LC;
- break;
- case AOT_MP2_SBR:
- case AOT_DABPLUS_SBR:
- hAacEnc->aot = AOT_SBR;
- break;
- case AOT_MP2_PS:
- case AOT_DABPLUS_PS:
- hAacEnc->aot = AOT_PS;
- break;
- default:
- hAacEnc->aot = hAacEnc->config->audioObjectType;
- }
+ hAacEnc->aot = hAacEnc->config->audioObjectType;
/* common things */
@@ -930,7 +955,7 @@ AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC hAacEnc,
transportEnc_WriteAccessUnit(
hTpEnc,
totalBits,
- FDKaacEnc_EncBitresToTpBitres(hAacEnc->bitrateMode, hAacEnc->qcKernel->bitResTot),
+ FDKaacEnc_EncBitresToTpBitres(hAacEnc),
cm->nChannelsEff);
/* write bitstream */
diff --git a/libAACenc/src/aacenc.h b/libAACenc/src/aacenc.h
index ed167c2..dd09ed9 100644
--- a/libAACenc/src/aacenc.h
+++ b/libAACenc/src/aacenc.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -98,6 +98,11 @@ amm-info@iis.fraunhofer.de
#include "sbr_encoder.h"
+#define BITRES_MAX_LD 4000
+#define BITRES_MIN_LD 500
+#define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */
+#define BITRATE_MIN_LD 12000 /* Min assumed bitrate for bitres calculation */
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -205,6 +210,8 @@ struct AACENC_CONFIG {
INT maxBitsPerFrame; /* maximum number of bits in AU */
INT bitreservoir; /* size of bitreservoir */
+ INT audioMuxVersion; /* audio mux version in loas/latm transport format */
+
UINT sbrRatio; /* sbr sampling rate ratio: dual- or single-rate */
UCHAR useTns; /* flag: use temporal noise shaping */
@@ -224,6 +231,36 @@ typedef struct {
typedef struct AAC_ENC *HANDLE_AAC_ENC;
/**
+ * \brief Calculate framesize in bits for given bit rate, frame length and sampling rate.
+ *
+ * \param bitRate Ttarget bitrate in bits per second.
+ * \param frameLength Number of audio samples in one frame.
+ * \param samplingRate Sampling rate in Hz.
+ *
+ * \return Framesize in bits per frame.
+*/
+INT FDKaacEnc_CalcBitsPerFrame(
+ const INT bitRate,
+ const INT frameLength,
+ const INT samplingRate
+ );
+
+/**
+ * \brief Calculate bitrate in bits per second for given framesize, frame length and sampling rate.
+ *
+ * \param bitsPerFrame Framesize in bits per frame.
+ * \param frameLength Number of audio samples in one frame.
+ * \param samplingRate Sampling rate in Hz.
+ *
+ * \return Bitrate in bits per second.
+*/
+INT FDKaacEnc_CalcBitrate(
+ const INT bitsPerFrame,
+ const INT frameLength,
+ const INT samplingRate
+ );
+
+/**
* \brief Limit given bit rate to a valid value
* \param hTpEnc transport encoder handle
* \param coreSamplingRate the sample rate to be used for the AAC encoder
diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp
index 3b641ab..fc58d6d 100644
--- a/libAACenc/src/aacenc_lib.cpp
+++ b/libAACenc/src/aacenc_lib.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -98,7 +98,7 @@ amm-info@iis.fraunhofer.de
/* Encoder library info */
#define AACENCODER_LIB_VL0 3
#define AACENCODER_LIB_VL1 4
-#define AACENCODER_LIB_VL2 12
+#define AACENCODER_LIB_VL2 22
#define AACENCODER_LIB_TITLE "AAC Encoder"
#ifdef __ANDROID__
#define AACENCODER_LIB_BUILD_DATE ""
@@ -153,6 +153,7 @@ typedef struct {
UINT userAfterburner;
UINT userFramelength;
UINT userAncDataRate;
+ UINT userPeakBitrate;
UCHAR userTns; /*!< Use TNS coding. */
UCHAR userPns; /*!< Use PNS coding. */
@@ -303,7 +304,7 @@ static AACENC_ERROR eldSbrConfigurator(
int i, cfgIdx = -1;
const ULONG channelBitrate = totalBitrate / FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff;
- for (i=0; i<(sizeof(eldSbrAutoConfigTab)/sizeof(ELD_SBR_CONFIGURATOR)); i++) {
+ for (i=0; i<(int)(sizeof(eldSbrAutoConfigTab)/sizeof(ELD_SBR_CONFIGURATOR)); i++) {
if ( (samplingRate <= eldSbrAutoConfigTab[i].samplingRate)
&& (channelBitrate >= eldSbrAutoConfigTab[i].bitrateRange) )
{
@@ -326,10 +327,7 @@ static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig)
{
INT sbrUsed = 0;
- if ( (hAacConfig->audioObjectType==AOT_SBR) || (hAacConfig->audioObjectType==AOT_PS)
- || (hAacConfig->audioObjectType==AOT_MP2_SBR) || (hAacConfig->audioObjectType==AOT_MP2_PS)
- || (hAacConfig->audioObjectType==AOT_DABPLUS_SBR) || (hAacConfig->audioObjectType==AOT_DABPLUS_PS)
- || (hAacConfig->audioObjectType==AOT_DRM_SBR) || (hAacConfig->audioObjectType==AOT_DRM_MPEG_PS) )
+ if ( (hAacConfig->audioObjectType==AOT_SBR) || (hAacConfig->audioObjectType==AOT_PS) )
{
sbrUsed = 1;
}
@@ -345,10 +343,7 @@ static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType)
{
INT psUsed = 0;
- if ( (audioObjectType==AOT_PS)
- || (audioObjectType==AOT_MP2_PS)
- || (audioObjectType==AOT_DABPLUS_PS)
- || (audioObjectType==AOT_DRM_MPEG_PS) )
+ if ( (audioObjectType==AOT_PS) )
{
psUsed = 1;
}
@@ -373,8 +368,7 @@ static SBR_PS_SIGNALING getSbrSignalingMode(
sbrSignaling = SIG_IMPLICIT; /* default: implicit signaling */
}
- if ((audioObjectType==AOT_AAC_LC) || (audioObjectType==AOT_SBR) || (audioObjectType==AOT_PS) ||
- (audioObjectType==AOT_MP2_AAC_LC) || (audioObjectType==AOT_MP2_SBR) || (audioObjectType==AOT_MP2_PS) ) {
+ if ( (audioObjectType==AOT_AAC_LC) || (audioObjectType==AOT_SBR) || (audioObjectType==AOT_PS) ) {
switch (transportType) {
case TT_MP4_ADIF:
case TT_MP4_ADTS:
@@ -430,22 +424,7 @@ static void FDKaacEnc_MapConfig(
cc->flags = 0;
- /* Map virtual aot to transport aot. */
- switch (hAacConfig->audioObjectType) {
- case AOT_MP2_AAC_LC:
- transport_AOT = AOT_AAC_LC;
- break;
- case AOT_MP2_SBR:
- transport_AOT = AOT_SBR;
- cc->flags |= CC_SBR;
- break;
- case AOT_MP2_PS:
- transport_AOT = AOT_PS;
- cc->flags |= CC_SBR;
- break;
- default:
- transport_AOT = hAacConfig->audioObjectType;
- }
+ transport_AOT = hAacConfig->audioObjectType;
if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) {
cc->flags |= (hAacConfig->syntaxFlags & AC_SBR_PRESENT) ? CC_SBR : 0;
@@ -511,16 +490,7 @@ static void FDKaacEnc_MapConfig(
cc->samplingRate = hAacConfig->sampleRate;
/* Mpeg-4 signaling for transport library. */
- switch ( hAacConfig->audioObjectType ) {
- case AOT_MP2_AAC_LC:
- case AOT_MP2_SBR:
- case AOT_MP2_PS:
- cc->flags &= ~CC_MPEG_ID; /* Required for ADTS. */
- cc->extAOT = AOT_NULL_OBJECT;
- break;
- default:
- cc->flags |= CC_MPEG_ID;
- }
+ cc->flags |= CC_MPEG_ID;
/* ER-tools signaling. */
cc->flags |= (hAacConfig->syntaxFlags & AC_ER_VCB11) ? CC_VCB11 : 0;
@@ -585,6 +555,7 @@ AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig,
config->userChannelMode = hAacConfig->channelMode;
config->userBitrate = hAacConfig->bitRate;
config->userBitrateMode = hAacConfig->bitrateMode;
+ config->userPeakBitrate = (UINT)-1;
config->userBandwidth = hAacConfig->bandWidth;
config->userTns = hAacConfig->useTns;
config->userPns = hAacConfig->usePns;
@@ -792,12 +763,15 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
hAacConfig->syntaxFlags = 0;
hAacConfig->epConfig = -1;
+ if (config->userTpType==TT_MP4_LATM_MCP1 || config->userTpType==TT_MP4_LATM_MCP0 || config->userTpType==TT_MP4_LOAS) {
+ hAacConfig->audioMuxVersion = config->userTpAmxv;
+ }
+ else {
+ hAacConfig->audioMuxVersion = -1;
+ }
+
/* Adapt internal AOT when necessary. */
switch ( hAacConfig->audioObjectType ) {
- case AOT_MP2_AAC_LC:
- case AOT_MP2_SBR:
- case AOT_MP2_PS:
- hAacConfig->usePns = 0;
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
@@ -839,11 +813,16 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
switch ( hAacConfig->audioObjectType ) {
case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD:
- if (config->userBitrateMode==8) {
- hAacConfig->bitrateMode = 0;
- }
if (config->userBitrateMode==0) {
- hAacConfig->bitreservoir = 100*config->nChannels; /* default, reduced bitreservoir */
+ /* bitreservoir = (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes; */
+ if ( isLowDelay(hAacConfig->audioObjectType) ) {
+ INT bitreservoir;
+ INT brPerChannel = hAacConfig->bitRate/hAacConfig->nChannels;
+ brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel));
+ FIXP_DBL slope = fDivNorm((brPerChannel-BITRATE_MIN_LD), BITRATE_MAX_LD-BITRATE_MIN_LD); /* calc slope for interpolation */
+ bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD-BITRES_MIN_LD)) + BITRES_MIN_LD; /* interpolate */
+ hAacConfig->bitreservoir = bitreservoir & ~7; /* align to bytes */
+ }
}
if (hAacConfig->bitrateMode!=0) {
return AACENC_INVALID_CONFIG;
@@ -884,6 +863,18 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
}
}
+ if ((hAacConfig->bitrateMode >= 0) && (hAacConfig->bitrateMode <= 5)) {
+ if ((INT)config->userPeakBitrate != -1) {
+ hAacConfig->maxBitsPerFrame = (FDKaacEnc_CalcBitsPerFrame(fMax(hAacConfig->bitRate, (INT)config->userPeakBitrate), hAacConfig->framelength, hAacConfig->sampleRate) + 7)&~7;
+ }
+ else {
+ hAacConfig->maxBitsPerFrame = -1;
+ }
+ if (hAacConfig->audioMuxVersion==2) {
+ hAacConfig->minBitsPerFrame = fMin(32*8, FDKaacEnc_CalcBitsPerFrame(hAacConfig->bitRate, hAacConfig->framelength, hAacConfig->sampleRate))&~7;
+ }
+ }
+
/* Initialize SBR parameters */
if ( (hAacConfig->audioObjectType==AOT_ER_AAC_ELD)
&& (config->userSbrEnabled == (UCHAR)-1) && (config->userSbrRatio==0) )
@@ -914,7 +905,7 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
}
else {
/* SBR ratio has been set by the user, so use it. */
- hAacConfig->sbrRatio = config->userSbrRatio;
+ hAacConfig->sbrRatio = isSbrActive(hAacConfig) ? config->userSbrRatio : 0;
}
{
@@ -1139,7 +1130,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
hAacConfig);
/* create flags for transport encoder */
- if (config->userTpAmxv == 1) {
+ if (config->userTpAmxv != 0) {
flags |= TP_FLAG_LATM_AMV;
}
/* Clear output buffer */
@@ -1569,7 +1560,7 @@ AACENC_ERROR aacEncEncode(
&& ((hAacEncoder->extParam.userChannelMode==MODE_1_2_2)||(hAacEncoder->extParam.userChannelMode==MODE_1_2_2_1)) )
{
/* Set matrix mixdown coefficient. */
- UINT pceValue = (UINT)( (1<<3) | ((matrix_mixdown_idx&0x3)<<1) | 1 );
+ UINT pceValue = (UINT)( (0<<3) | ((matrix_mixdown_idx&0x3)<<1) | 1 );
if (hAacEncoder->extParam.userPceAdditions != pceValue) {
hAacEncoder->extParam.userPceAdditions = pceValue;
hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
@@ -1785,19 +1776,16 @@ AACENC_ERROR aacEncoder_SetParam(
/* check if AOT matches the allocated modules */
switch ( value ) {
case AOT_PS:
- case AOT_MP2_PS:
if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) {
err = AACENC_INVALID_CONFIG;
goto bail;
}
case AOT_SBR:
- case AOT_MP2_SBR:
if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) {
err = AACENC_INVALID_CONFIG;
goto bail;
}
case AOT_AAC_LC:
- case AOT_MP2_AAC_LC:
case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD:
if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) {
@@ -1823,11 +1811,7 @@ AACENC_ERROR aacEncoder_SetParam(
if (settings->userBitrateMode != value) {
switch ( value ) {
case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
+ case 1: case 2: case 3: case 4: case 5:
case 8:
settings->userBitrateMode = value;
hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
@@ -1978,6 +1962,16 @@ AACENC_ERROR aacEncoder_SetParam(
hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
}
break;
+ case AACENC_AUDIOMUXVER:
+ if (settings->userTpAmxv != value) {
+ if ( !((value==0) || (value==1) || (value==2)) ) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userTpAmxv = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT;
+ }
+ break;
case AACENC_TPSUBFRAMES:
if (settings->userTpNsubFrames != value) {
if (! ( (value>=1) && (value<=4) ) ) {
@@ -2003,7 +1997,7 @@ AACENC_ERROR aacEncoder_SetParam(
break;
case AACENC_METADATA_MODE:
if ((UINT)settings->userMetaDataMode != value) {
- if ( !((value>=0) && (value<=2)) ) {
+ if ( !(((INT)value>=0) && ((INT)value<=2)) ) {
err = AACENC_INVALID_CONFIG;
break;
}
@@ -2011,6 +2005,12 @@ AACENC_ERROR aacEncoder_SetParam(
hAacEncoder->InitFlags |= AACENC_INIT_CONFIG;
}
break;
+ case AACENC_PEAK_BITRATE:
+ if (settings->userPeakBitrate != value) {
+ settings->userPeakBitrate = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
+ }
+ break;
default:
err = AACENC_UNSUPPORTED_PARAMETER;
break;
@@ -2081,6 +2081,9 @@ UINT aacEncoder_GetParam(
case AACENC_HEADER_PERIOD:
value = (UINT)hAacEncoder->coderConfig.headerPeriod;
break;
+ case AACENC_AUDIOMUXVER:
+ value = (UINT)hAacEncoder->aacConfig.audioMuxVersion;
+ break;
case AACENC_TPSUBFRAMES:
value = (UINT)settings->userTpNsubFrames;
break;
@@ -2093,6 +2096,12 @@ UINT aacEncoder_GetParam(
case AACENC_METADATA_MODE:
value = (hAacEncoder->metaDataAllowed==0) ? 0 : (UINT)settings->userMetaDataMode;
break;
+ case AACENC_PEAK_BITRATE:
+ value = (UINT)-1; /* peak bitrate parameter is meaningless */
+ if ( ((INT)hAacEncoder->extParam.userPeakBitrate!=-1) ) {
+ value = (UINT)(fMax((INT)hAacEncoder->extParam.userPeakBitrate, hAacEncoder->aacConfig.bitRate)); /* peak bitrate parameter is in use */
+ }
+ break;
default:
//err = MPS_INVALID_PARAMETER;
break;
diff --git a/libAACenc/src/aacenc_tns.cpp b/libAACenc/src/aacenc_tns.cpp
index 85aea65..9a07e8f 100644
--- a/libAACenc/src/aacenc_tns.cpp
+++ b/libAACenc/src/aacenc_tns.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -95,13 +95,7 @@ amm-info@iis.fraunhofer.de
#include "aacEnc_rom.h"
#include "aacenc_tns.h"
-enum {
- HIFILT = 0, /* index of higher filter */
- LOFILT = 1 /* index of lower filter */
-};
-
-
-#define FILTER_DIRECTION 0
+#define FILTER_DIRECTION 0 /* 0 = up, 1 = down */
static const FIXP_DBL acfWindowLong[12+3+1] = {
0x7fffffff,0x7fb80000,0x7ee00000,0x7d780000,0x7b800000,0x78f80000,0x75e00000,0x72380000,
@@ -112,20 +106,6 @@ static const FIXP_DBL acfWindowShort[4+3+1] = {
0x7fffffff,0x7e000000,0x78000000,0x6e000000,0x60000000,0x4e000000,0x38000000,0x1e000000
};
-
-typedef struct {
- INT filterEnabled[MAX_NUM_OF_FILTERS];
- INT threshOn[MAX_NUM_OF_FILTERS]; /* min. prediction gain for using tns TABUL*/
- INT filterStartFreq[MAX_NUM_OF_FILTERS]; /* lowest freq for lpc TABUL*/
- INT tnsLimitOrder[MAX_NUM_OF_FILTERS]; /* Limit for TNS order TABUL*/
- INT tnsFilterDirection[MAX_NUM_OF_FILTERS]; /* Filtering direction, 0=up, 1=down TABUL */
- INT acfSplit[MAX_NUM_OF_FILTERS];
- FIXP_DBL tnsTimeResolution[MAX_NUM_OF_FILTERS]; /* TNS max. time resolution TABUL. Should be fract but MSVC won't compile then */
- INT seperateFiltersAllowed;
-
-} TNS_PARAMETER_TABULATED;
-
-
typedef struct{
INT bitRateFrom[2]; /* noneSbr=0, useSbr=1 */
INT bitRateTo[2]; /* noneSbr=0, useSbr=1 */
@@ -373,6 +353,7 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate,
INT channels,
INT blockType,
INT granuleLength,
+ INT isLowDelay,
INT ldSbrPresent,
TNS_CONFIG *tC,
PSY_CONFIGURATION *pC,
@@ -385,6 +366,8 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate,
if (channels <= 0)
return (AAC_ENCODER_ERROR)1;
+ tC->isLowDelay = isLowDelay;
+
/* initialize TNS filter flag, order, and coefficient resolution (in bits per coeff) */
tC->tnsActive = (active) ? TRUE : FALSE;
tC->maxOrder = (blockType == SHORT_WINDOW) ? 5 : 12; /* maximum: 7, 20 */
@@ -450,27 +433,14 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate,
const TNS_PARAMETER_TABULATED* pCfg = FDKaacEnc_GetTnsParam(bitRate, channels, ldSbrPresent);
if ( pCfg != NULL ) {
+
+ FDKmemcpy(&(tC->confTab), pCfg, sizeof(tC->confTab));
+
tC->lpcStartBand[HIFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[HIFILT], sampleRate, pC->sfbCnt, pC->sfbOffset);
tC->lpcStartLine[HIFILT] = pC->sfbOffset[tC->lpcStartBand[HIFILT]];
tC->lpcStartBand[LOFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[LOFILT], sampleRate, pC->sfbCnt, pC->sfbOffset);
tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]];
- tC->confTab.threshOn[HIFILT] = pCfg->threshOn[HIFILT];
- tC->confTab.threshOn[LOFILT] = pCfg->threshOn[LOFILT];
-
- tC->confTab.tnsLimitOrder[HIFILT] = pCfg->tnsLimitOrder[HIFILT];
- tC->confTab.tnsLimitOrder[LOFILT] = pCfg->tnsLimitOrder[LOFILT];
-
- tC->confTab.tnsFilterDirection[HIFILT] = pCfg->tnsFilterDirection[HIFILT];
- tC->confTab.tnsFilterDirection[LOFILT] = pCfg->tnsFilterDirection[LOFILT];
-
- tC->confTab.acfSplit[HIFILT] = pCfg->acfSplit[HIFILT];
- tC->confTab.acfSplit[LOFILT] = pCfg->acfSplit[LOFILT];
-
- tC->confTab.filterEnabled[HIFILT] = pCfg->filterEnabled[HIFILT];
- tC->confTab.filterEnabled[LOFILT] = pCfg->filterEnabled[LOFILT];
- tC->confTab.seperateFiltersAllowed = pCfg->seperateFiltersAllowed;
-
FDKaacEnc_CalcGaussWindow(tC->acfWindow[HIFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[HIFILT], TNS_TIMERES_SCALE);
FDKaacEnc_CalcGaussWindow(tC->acfWindow[LOFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[LOFILT], TNS_TIMERES_SCALE);
}
@@ -614,6 +584,7 @@ static inline FIXP_DBL FDKaacEnc_AutoCorrNormFac(
static void FDKaacEnc_MergedAutoCorrelation(
const FIXP_DBL *spectrum,
+ const INT isLowDelay,
const FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER+3+1],
const INT lpcStartLine[MAX_NUM_OF_FILTERS],
const INT lpcStopLine,
@@ -633,6 +604,8 @@ static void FDKaacEnc_MergedAutoCorrelation(
FDKmemclear(&_rxx1[0], sizeof(FIXP_DBL)*(maxOrder+1));
FDKmemclear(&_rxx2[0], sizeof(FIXP_DBL)*(maxOrder+1));
+ idx0 = idx1 = idx2 = idx3 = idx4 = 0;
+
/* MDCT line indices separating the 1st, 2nd, 3rd, and 4th analysis quarters */
if ( (acfSplit[LOFILT]==-1) || (acfSplit[HIFILT]==-1) ) {
/* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the spectrum */
@@ -676,17 +649,27 @@ static void FDKaacEnc_MergedAutoCorrelation(
/* compute energy normalization factors, i. e. 1/energy (saves some divisions) */
if (rxx1_0 != FL2FXCONST_DBL(0.f))
{
- INT sc_fac1 = -1;
- FIXP_DBL fac1 = FDKaacEnc_AutoCorrNormFac(rxx1_0, ((-2*sc1)+nsc1), &sc_fac1);
- _rxx1[0] = scaleValue(fMult(rxx1_0,fac1),sc_fac1);
+ INT sc_fac1 = -1;
+ FIXP_DBL fac1 = FDKaacEnc_AutoCorrNormFac(rxx1_0, ((-2*sc1)+nsc1), &sc_fac1);
+ _rxx1[0] = scaleValue(fMult(rxx1_0,fac1),sc_fac1);
+ if (isLowDelay)
+ {
for (lag = 1; lag <= maxOrder; lag++) {
/* compute energy-normalized and windowed autocorrelation values at this lag */
+ FIXP_DBL x1 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1);
+ _rxx1[lag] = fMult(scaleValue(fMult(x1,fac1),sc_fac1), acfWindow[LOFILT][lag]);
+ }
+ }
+ else
+ {
+ for (lag = 1; lag <= maxOrder; lag++) {
if ((3 * lag) <= maxOrder + 3) {
FIXP_DBL x1 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1);
_rxx1[lag] = fMult(scaleValue(fMult(x1,fac1),sc_fac1), acfWindow[LOFILT][3*lag]);
}
}
+ }
}
/* auto corr over upper 3/4 of spectrum */
@@ -762,8 +745,12 @@ INT FDKaacEnc_TnsDetect(
: &tnsData->dataRaw.Long.subBlockInfo;
tnsData->filtersMerged = FALSE;
- tsbi->tnsActive = FALSE;
- tsbi->predictionGain = 1000;
+
+ tsbi->tnsActive[HIFILT] = FALSE;
+ tsbi->predictionGain[HIFILT] = 1000;
+ tsbi->tnsActive[LOFILT] = FALSE;
+ tsbi->predictionGain[LOFILT] = 1000;
+
tnsInfo->numOfFilters[subBlockNumber] = 0;
tnsInfo->coefRes[subBlockNumber] = tC->coefRes;
for (i = 0; i < tC->maxOrder; i++) {
@@ -779,6 +766,7 @@ INT FDKaacEnc_TnsDetect(
FDKaacEnc_MergedAutoCorrelation(
spectrum,
+ tC->isLowDelay,
tC->acfWindow,
tC->lpcStartLine,
tC->lpcStopLine,
@@ -788,7 +776,7 @@ INT FDKaacEnc_TnsDetect(
rxx2);
/* compute higher TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */
- tsbi->predictionGain = FDKaacEnc_AutoToParcor(rxx2, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT]);
+ tsbi->predictionGain[HIFILT] = FDKaacEnc_AutoToParcor(rxx2, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT]);
/* non-linear quantization of TNS lattice coefficients with given resolution */
FDKaacEnc_Parcor2Index(
@@ -815,9 +803,9 @@ INT FDKaacEnc_TnsDetect(
tnsInfo->length[subBlockNumber][HIFILT] = sfbCnt - tC->lpcStartBand[HIFILT];
/* disable TNS if predictionGain is less than 3dB or sumSqrCoef is too small */
- if ((tsbi->predictionGain > tC->confTab.threshOn[HIFILT]) || (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT]/2 + 2)))
+ if ((tsbi->predictionGain[HIFILT] > tC->confTab.threshOn[HIFILT]) || (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT]/2 + 2)))
{
- tsbi->tnsActive = TRUE;
+ tsbi->tnsActive[HIFILT] = TRUE;
tnsInfo->numOfFilters[subBlockNumber]++;
/* compute second filter for lower quarter; only allowed for long windows! */
@@ -857,6 +845,7 @@ INT FDKaacEnc_TnsDetect(
|| ( (sumSqrCoef > 9) && (sumSqrCoef < 22 * tC->confTab.tnsLimitOrder[LOFILT]) ) )
{
/* compare lower to upper filter; if they are very similar, merge them */
+ tsbi->tnsActive[LOFILT] = TRUE;
sumSqrCoef = 0;
for (i = 0; i < tC->confTab.tnsLimitOrder[LOFILT]; i++) {
sumSqrCoef += FDKabs(tnsInfo->coef[subBlockNumber][HIFILT][i] - tnsInfo->coef[subBlockNumber][LOFILT][i]);
@@ -884,6 +873,8 @@ INT FDKaacEnc_TnsDetect(
tnsInfo->numOfFilters[subBlockNumber]++;
}
} /* filter lower part */
+ tsbi->predictionGain[LOFILT]=predGain;
+
} /* second filter allowed */
} /* if predictionGain > 1437 ... */
} /* maxOrder > 0 && tnsActive */
@@ -944,7 +935,7 @@ void FDKaacEnc_TnsSync(
INT doSync = 1, absDiffSum = 0;
/* if TNS is active in at least one channel, check if ParCor coefficients of higher filter are similar */
- if (pSbInfoDestW->tnsActive || pSbInfoSrcW->tnsActive) {
+ if (pSbInfoDestW->tnsActive[HIFILT] || pSbInfoSrcW->tnsActive[HIFILT]) {
for (i = 0; i < tC->maxOrder; i++) {
absDiff = FDKabs(tnsInfoDest->coef[w][HIFILT][i] - tnsInfoSrc->coef[w][HIFILT][i]);
absDiffSum += absDiff;
@@ -957,12 +948,12 @@ void FDKaacEnc_TnsSync(
if (doSync) {
/* if no significant difference was detected, synchronize coefficient sets */
- if (pSbInfoSrcW->tnsActive) {
+ if (pSbInfoSrcW->tnsActive[HIFILT]) {
/* no dest filter, or more dest than source filters: use one dest filter */
- if ((!pSbInfoDestW->tnsActive) ||
- ((pSbInfoDestW->tnsActive) && (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w])))
+ if ((!pSbInfoDestW->tnsActive[HIFILT]) ||
+ ((pSbInfoDestW->tnsActive[HIFILT]) && (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w])))
{
- pSbInfoDestW->tnsActive = tnsInfoDest->numOfFilters[w] = 1;
+ pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 1;
}
tnsDataDest->filtersMerged = tnsDataSrc->filtersMerged;
tnsInfoDest->order [w][HIFILT] = tnsInfoSrc->order [w][HIFILT];
@@ -975,7 +966,7 @@ void FDKaacEnc_TnsSync(
}
}
else
- pSbInfoDestW->tnsActive = tnsInfoDest->numOfFilters[w] = 0;
+ pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 0;
}
}
@@ -1012,8 +1003,8 @@ INT FDKaacEnc_TnsEncode(
{
INT i, startLine, stopLine;
- if ( ( (blockType == SHORT_WINDOW) && (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber].tnsActive) )
- || ( (blockType != SHORT_WINDOW) && (!tnsData->dataRaw.Long.subBlockInfo.tnsActive) ) )
+ if ( ( (blockType == SHORT_WINDOW) && (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber].tnsActive[HIFILT]) )
+ || ( (blockType != SHORT_WINDOW) && (!tnsData->dataRaw.Long.subBlockInfo.tnsActive[HIFILT]) ) )
{
return 1;
}
@@ -1129,8 +1120,9 @@ static INT FDKaacEnc_AutoToParcor(
FIXP_DBL *RESTRICT workBuffer = parcorWorkBuffer;
const FIXP_DBL autoCorr_0 = input[0];
+ FDKmemclear(reflCoeff,numOfCoeff*sizeof(FIXP_DBL));
+
if((FIXP_DBL)input[0] == FL2FXCONST_DBL(0.0)) {
- FDKmemclear(reflCoeff,numOfCoeff*sizeof(FIXP_DBL));
return(predictionGain);
}
diff --git a/libAACenc/src/aacenc_tns.h b/libAACenc/src/aacenc_tns.h
index f2b731f..2824cbc 100644
--- a/libAACenc/src/aacenc_tns.h
+++ b/libAACenc/src/aacenc_tns.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -117,21 +117,25 @@ amm-info@iis.fraunhofer.de
#define MAX_NUM_OF_FILTERS 2
+#define HIFILT 0 /* index of higher filter */
+#define LOFILT 1 /* index of lower filter */
-typedef struct{ /*stuff that is tabulated dependent on bitrate etc. */
- INT filterEnabled[MAX_NUM_OF_FILTERS];
- INT threshOn[MAX_NUM_OF_FILTERS]; /* min. prediction gain for using tns TABUL*/
- INT tnsLimitOrder[MAX_NUM_OF_FILTERS]; /* Limit for TNS order TABUL*/
- INT tnsFilterDirection[MAX_NUM_OF_FILTERS]; /* Filtering direction, 0=up, 1=down TABUL */
- INT acfSplit[MAX_NUM_OF_FILTERS];
- INT seperateFiltersAllowed;
-
-}TNS_CONFIG_TABULATED;
+typedef struct{ /* stuff that is tabulated dependent on bitrate etc. */
+ INT filterEnabled[MAX_NUM_OF_FILTERS];
+ INT threshOn[MAX_NUM_OF_FILTERS]; /* min. prediction gain for using tns TABUL*/
+ INT filterStartFreq[MAX_NUM_OF_FILTERS]; /* lowest freq for lpc TABUL*/
+ INT tnsLimitOrder[MAX_NUM_OF_FILTERS]; /* Limit for TNS order TABUL*/
+ INT tnsFilterDirection[MAX_NUM_OF_FILTERS]; /* Filtering direction, 0=up, 1=down TABUL */
+ INT acfSplit[MAX_NUM_OF_FILTERS];
+ FIXP_DBL tnsTimeResolution[MAX_NUM_OF_FILTERS]; /* TNS max. time resolution TABUL. Should be fract but MSVC won't compile then */
+ INT seperateFiltersAllowed;
+} TNS_PARAMETER_TABULATED;
typedef struct { /*assigned at InitTime*/
- TNS_CONFIG_TABULATED confTab;
+ TNS_PARAMETER_TABULATED confTab;
+ INT isLowDelay;
INT tnsActive;
INT maxOrder; /* max. order of tns filter */
INT coefRes;
@@ -148,8 +152,8 @@ typedef struct { /*assigned at InitTime*/
typedef struct {
- INT tnsActive;
- INT predictionGain;
+ INT tnsActive[MAX_NUM_OF_FILTERS];
+ INT predictionGain[MAX_NUM_OF_FILTERS];
} TNS_SUBBLOCK_INFO;
typedef struct{ /*changed at runTime*/
diff --git a/libAACenc/src/adj_thr.cpp b/libAACenc/src/adj_thr.cpp
index 6433633..a79a9ae 100644
--- a/libAACenc/src/adj_thr.cpp
+++ b/libAACenc/src/adj_thr.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -130,14 +130,14 @@ the crash recovery strategy will be activated once.
typedef struct {
INT bitrate;
- LONG bits2PeFactor_mono;
- LONG bits2PeFactor_mono_slope;
- LONG bits2PeFactor_stereo;
- LONG bits2PeFactor_stereo_slope;
- LONG bits2PeFactor_mono_scfOpt;
- LONG bits2PeFactor_mono_scfOpt_slope;
- LONG bits2PeFactor_stereo_scfOpt;
- LONG bits2PeFactor_stereo_scfOpt_slope;
+ ULONG bits2PeFactor_mono;
+ ULONG bits2PeFactor_mono_slope;
+ ULONG bits2PeFactor_stereo;
+ ULONG bits2PeFactor_stereo_slope;
+ ULONG bits2PeFactor_mono_scfOpt;
+ ULONG bits2PeFactor_mono_scfOpt_slope;
+ ULONG bits2PeFactor_stereo_scfOpt;
+ ULONG bits2PeFactor_stereo_scfOpt_slope;
} BIT_PE_SFAC;
@@ -153,10 +153,10 @@ static const BIT_PE_SFAC S_Bits2PeTab16000[] = {
{ 24000, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413},
{ 32000, 0x247AE148, 0x11B1D92B, 0x23851EB8, 0x01F75105, 0x247AE148, 0x110A137F, 0x23851EB8, 0x01F75105},
{ 48000, 0x2D1EB852, 0x6833C600, 0x247AE148, 0x014F8B59, 0x2CCCCCCD, 0x68DB8BAC, 0x247AE148, 0x01F75105},
- { 64000, 0x60000000, 0x00000000, 0x251EB852, 0x154C985F, 0x60000000, 0x00000000, 0x2570A3D7, 0x154C985F},
- { 96000, 0x60000000, 0x00000000, 0x39EB851F, 0x088509C0, 0x60000000, 0x00000000, 0x3A3D70A4, 0x088509C0},
- {128000, 0x60000000, 0x00000000, 0x423D70A4, 0x18A43BB4, 0x60000000, 0x00000000, 0x428F5C29, 0x181E03F7},
- {148000, 0x60000000, 0x00000000, 0x5147AE14, 0x00000000, 0x60000000, 0x00000000, 0x5147AE14, 0x00000000}
+ { 64000, 0x25c28f40, 0x00000000, 0x251EB852, 0x01480000, 0x25c28f40, 0x00000000, 0x2570A3D7, 0x01480000},
+ { 96000, 0x25c28f40, 0x00000000, 0x26000000, 0x01000000, 0x25c28f40, 0x00000000, 0x26000000, 0x01000000},
+ {128000, 0x25c28f40, 0x00000000, 0x270a3d80, 0x01000000, 0x25c28f40, 0x00000000, 0x270a3d80, 0x01000000},
+ {148000, 0x25c28f40, 0x00000000, 0x28000000, 0x00000000, 0x25c28f40, 0x00000000, 0x28000000, 0x00000000}
};
static const BIT_PE_SFAC S_Bits2PeTab22050[] = {
@@ -166,8 +166,8 @@ static const BIT_PE_SFAC S_Bits2PeTab22050[] = {
{ 48000, 0x23d70a3d, 0x014f8b59, 0x2199999a, 0x03eea20a, 0x23d70a3d, 0x14f8b59, 0x2199999a, 0x03eea20a},
{ 64000, 0x247ae148, 0x08d8ec96, 0x23851eb8, 0x00fba882, 0x247ae148, 0x88509c0, 0x23851eb8, 0x00fba882},
{ 96000, 0x2d1eb852, 0x3419e300, 0x247ae148, 0x00a7c5ac, 0x2ccccccd, 0x346dc5d6, 0x247ae148, 0x00fba882},
- {128000, 0x60000000, 0x00000000, 0x251eb852, 0x029f16b1, 0x60000000, 0x00000000, 0x2570a3d7, 0x009f16b1},
- {148000, 0x60000000, 0x00000000, 0x26b851ec, 0x00000000, 0x60000000, 0x00000000, 0x270a3d71, 0x00000000}
+ {128000, 0x25c28f40, 0x00000000, 0x251eb852, 0x029f16b1, 0x60000000, 0x25c28f40, 0x2570a3d7, 0x009f16b1},
+ {148000, 0x25c28f40, 0x00000000, 0x26b851ec, 0x00000000, 0x60000000, 0x25c28f40, 0x270a3d71, 0x00000000}
};
static const BIT_PE_SFAC S_Bits2PeTab24000[] = {
@@ -178,21 +178,21 @@ static const BIT_PE_SFAC S_Bits2PeTab24000[] = {
{ 64000, 0x24cccccd, 0x05e5f30e, 0x22e147ae, 0x01a36e2f, 0x24cccccd, 0x05e5f30e, 0x23333333, 0x014f8b59},
{ 96000, 0x2a8f5c29, 0x24b33db0, 0x247ae148, 0x00fba882, 0x2a8f5c29, 0x26fe718b, 0x247ae148, 0x00fba882},
{128000, 0x4e666666, 0x1cd5f99c, 0x2570a3d7, 0x010c6f7a, 0x50a3d70a, 0x192a7371, 0x2570a3d7, 0x010c6f7a},
- {148000, 0x60000000, 0x00000000, 0x26147ae1, 0x00000000, 0x60000000, 0x00000000, 0x26147ae1, 0x00000000}
+ {148000, 0x25c28f40, 0x00000000, 0x26147ae1, 0x00000000, 0x25c28f40, 0x00000000, 0x26147ae1, 0x00000000}
};
static const BIT_PE_SFAC S_Bits2PeTab32000[] = {
- { 16000, 0x1199999a, 0x20c49ba6, 0x00000000, 0x4577d955, 0x00000000, 0x60fe4799, 0x00000000, 0x00000000},
- { 24000, 0x1999999a, 0x0fba8827, 0x10f5c28f, 0x1b866e44, 0x17ae147b, 0x0fba8827, 0x00000000, 0x4d551d69},
+ { 16000, 0x247ae140, 0xFFFFAC1E, 0x270a3d80, 0xFFFE9B7C, 0x14ccccc0, 0x000110A1, 0x15c28f60, 0xFFFEEF5F},
+ { 24000, 0x23333340, 0x0fba8827, 0x21999980, 0x1b866e44, 0x18f5c280, 0x0fba8827, 0x119999a0, 0x4d551d69},
{ 32000, 0x1d70a3d7, 0x07357e67, 0x17ae147b, 0x09d49518, 0x1b851eb8, 0x0a7c5ac4, 0x12e147ae, 0x110a137f},
{ 48000, 0x20f5c28f, 0x049667b6, 0x1c7ae148, 0x053e2d62, 0x20a3d70a, 0x053e2d62, 0x1b333333, 0x05e5f30e},
{ 64000, 0x23333333, 0x029f16b1, 0x1f0a3d71, 0x02f2f987, 0x23333333, 0x029f16b1, 0x1e147ae1, 0x03eea20a},
{ 96000, 0x25c28f5c, 0x2c3c9eed, 0x21eb851f, 0x01f75105, 0x25c28f5c, 0x0a7c5ac4, 0x21eb851f, 0x01a36e2f},
{128000, 0x50f5c28f, 0x18a43bb4, 0x23d70a3d, 0x010c6f7a, 0x30000000, 0x168b5cc0, 0x23851eb8, 0x0192a737},
- {148000, 0x60000000, 0x00000000, 0x247ae148, 0x00dfb23b, 0x3dc28f5c, 0x300f4aaf, 0x247ae148, 0x01bf6476},
- {160000, 0x60000000, 0xb15b5740, 0x24cccccd, 0x053e2d62, 0x4f5c28f6, 0xbefd0072, 0x251eb852, 0x04fb1184},
- {200000, 0x00000000, 0x00000000, 0x2b333333, 0x0836be91, 0x00000000, 0x00000000, 0x2b333333, 0x0890390f},
- {320000, 0x00000000, 0x00000000, 0x4947ae14, 0x00000000, 0x00000000, 0x00000000, 0x4a8f5c29, 0x00000000}
+ {148000, 0x25c28f40, 0x00000000, 0x247ae148, 0x00dfb23b, 0x3dc28f5c, 0x300f4aaf, 0x247ae148, 0x01bf6476},
+ {160000, 0x25c28f40, 0xb15b5740, 0x24cccccd, 0x053e2d62, 0x4f5c28f6, 0xbefd0072, 0x251eb852, 0x04fb1184},
+ {200000, 0x25c28f40, 0x00000000, 0x2b333333, 0x0836be91, 0x25c28f40, 0x00000000, 0x2b333333, 0x0890390f},
+ {320000, 0x25c28f40, 0x00000000, 0x4947ae14, 0x00000000, 0x25c28f40, 0x00000000, 0x4a8f5c29, 0x00000000}
};
static const BIT_PE_SFAC S_Bits2PeTab44100[] = {
@@ -205,8 +205,8 @@ static const BIT_PE_SFAC S_Bits2PeTab44100[] = {
{128000, 0x2ae147ae, 0x1b435265, 0x223d70a4, 0x0192a737, 0x2a3d70a4, 0x1040bfe4, 0x21eb851f, 0x0192a737},
{148000, 0x3b851eb8, 0x2832069c, 0x23333333, 0x00dfb23b, 0x3428f5c3, 0x2054c288, 0x22e147ae, 0x00dfb23b},
{160000, 0x4a3d70a4, 0xc32ebe5a, 0x23851eb8, 0x01d5c316, 0x40000000, 0xcb923a2b, 0x23333333, 0x01d5c316},
- {200000, 0x00000000, 0x00000000, 0x25c28f5c, 0x0713f078, 0x00000000, 0x00000000, 0x2570a3d7, 0x072a4f17},
- {320000, 0x00000000, 0x00000000, 0x3fae147b, 0x00000000, 0x00000000, 0x00000000, 0x3fae147b, 0x00000000}
+ {200000, 0x25c28f40, 0x00000000, 0x25c28f5c, 0x0713f078, 0x25c28f40, 0x00000000, 0x2570a3d7, 0x072a4f17},
+ {320000, 0x25c28f40, 0x00000000, 0x3fae147b, 0x00000000, 0x25c28f40, 0x00000000, 0x3fae147b, 0x00000000}
};
static const BIT_PE_SFAC S_Bits2PeTab48000[] = {
@@ -219,8 +219,8 @@ static const BIT_PE_SFAC S_Bits2PeTab48000[] = {
{128000, 0x28f5c28f, 0x14727dcc, 0x2147ae14, 0x0218def4, 0x2851eb85, 0x0e27e0f0, 0x20f5c28f, 0x0218def4},
{148000, 0x3570a3d7, 0x1cd5f99c, 0x228f5c29, 0x01bf6476, 0x30f5c28f, 0x18777e75, 0x223d70a4, 0x01bf6476},
{160000, 0x40000000, 0xcb923a2b, 0x23333333, 0x0192a737, 0x39eb851f, 0xd08d4bae, 0x22e147ae, 0x0192a737},
- {200000, 0x00000000, 0x00000000, 0x251eb852, 0x06775a1b, 0x00000000, 0x00000000, 0x24cccccd, 0x06a4175a},
- {320000, 0x00000000, 0x00000000, 0x3ccccccd, 0x00000000, 0x00000000, 0x00000000, 0x3d1eb852, 0x00000000}
+ {200000, 0x25c28f40, 0x00000000, 0x251eb852, 0x06775a1b, 0x25c28f40, 0x00000000, 0x24cccccd, 0x06a4175a},
+ {320000, 0x25c28f40, 0x00000000, 0x3ccccccd, 0x00000000, 0x25c28f40, 0x00000000, 0x3d1eb852, 0x00000000}
};
static const BITS2PE_CFG_TAB bits2PeConfigTab[] = {
@@ -258,6 +258,7 @@ static void FDKaacEnc_InitBits2PeFactor(
const INT nChannels,
const INT sampleRate,
const INT advancedBitsToPe,
+ const INT dZoneQuantEnable,
const INT invQuant
)
{
@@ -329,7 +330,32 @@ static void FDKaacEnc_InitBits2PeFactor(
} /* advancedBitsToPe */
- /* return bits2pe factor */
+ if (dZoneQuantEnable)
+ {
+ if(bit2PE_m >= (FL2FXCONST_DBL(0.6f))>>bit2PE_e)
+ {
+ /* Additional headroom for addition */
+ bit2PE_m >>= 1;
+ bit2PE_e += 1;
+ }
+
+ /* the quantTendencyCompensator compensates a lower bit consumption due to increasing the tendency to quantize low spectral values to the lower quantizer border for bitrates below a certain bitrate threshold --> see also function calcSfbDistLD in quantize.c */
+ if ((bitRate/nChannels > 32000) && (bitRate/nChannels <= 40000)) {
+ bit2PE_m += (FL2FXCONST_DBL(0.4f))>>bit2PE_e;
+ }
+ else if (bitRate/nChannels > 20000) {
+ bit2PE_m += (FL2FXCONST_DBL(0.3f))>>bit2PE_e;
+ }
+ else if (bitRate/nChannels >= 16000) {
+ bit2PE_m += (FL2FXCONST_DBL(0.3f))>>bit2PE_e;
+ }
+ else {
+ bit2PE_m += (FL2FXCONST_DBL(0.0f))>>bit2PE_e;
+ }
+ }
+
+
+ /***** 3.) Return bits2pe factor *****/
*bits2PeFactor_m = bit2PE_m;
*bits2PeFactor_e = bit2PE_e;
}
@@ -1649,6 +1675,7 @@ static void FDKaacEnc_adaptThresholdsToPe(CHANNEL_MAPPING* cm,
QC_OUT_ELEMENT* qcElement[(8)],
PSY_OUT_ELEMENT* psyOutElement[(8)],
const INT desiredPe,
+ const INT maxIter2ndGuess,
const INT processElements,
const INT elementOffset)
{
@@ -1733,7 +1760,7 @@ static void FDKaacEnc_adaptThresholdsToPe(CHANNEL_MAPPING* cm,
/* Part III: Iterate until bit constraints are met */
/* -------------------------------------------------- */
iter = 0;
- while ((fixp_abs(redPeGlobal - desiredPe) > fMultI(FL2FXCONST_DBL(0.05f),desiredPe)) && (iter < 1)) {
+ while ((fixp_abs(redPeGlobal - desiredPe) > fMultI(FL2FXCONST_DBL(0.05f),desiredPe)) && (iter < maxIter2ndGuess)) {
INT desiredPeNoAHGlobal;
INT redPeNoAHGlobal = 0;
@@ -2138,7 +2165,7 @@ static FIXP_DBL FDKaacEnc_bitresCalcBitFac(const INT bitresBits,
bresParam->clipSpendLow, bresParam->clipSpendHigh,
bresParam->minBitSpend, bresParam->maxBitSpend, bitspend_slope);
- pe_pers = fDivNorm(pex - adjThrChan->peMin, adjThrChan->peMax - adjThrChan->peMin);
+ pe_pers = (pex > adjThrChan->peMin) ? fDivNorm(pex - adjThrChan->peMin, adjThrChan->peMax - adjThrChan->peMin) : 0;
tmp_fix = fMult(((FIXP_DBL)bitSpend + (FIXP_DBL)bitSave), pe_pers);
bitresFac_fix = (UNITY>>1) - ((FIXP_DBL)bitSave>>1) + (tmp_fix>>1); qbres = (DFRACT_BITS-2);
@@ -2225,7 +2252,8 @@ void FDKaacEnc_AdjThrInit(
INT nChannelsEff,
INT sampleRate,
INT advancedBitsToPe,
- FIXP_DBL vbrQualFactor
+ FIXP_DBL vbrQualFactor,
+ const INT dZoneQuantEnable
)
{
INT i;
@@ -2233,6 +2261,10 @@ void FDKaacEnc_AdjThrInit(
FIXP_DBL POINT8 = FL2FXCONST_DBL(0.8f);
FIXP_DBL POINT6 = FL2FXCONST_DBL(0.6f);
+ /* Max number of iterations in second guess is 3 for lowdelay aot and for configurations with
+ multiple audio elements in general, otherwise iteration value is always 1. */
+ hAdjThr->maxIter2ndGuess = (advancedBitsToPe!=0 || nElements>1) ? 3 : 1;
+
/* common for all elements: */
/* parameters for bitres control */
hAdjThr->bresParamLong.clipSaveLow = (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */
@@ -2313,10 +2345,11 @@ void FDKaacEnc_AdjThrInit(
FDKaacEnc_InitBits2PeFactor(
&atsElem->bits2PeFactor_m,
&atsElem->bits2PeFactor_e,
- chBitrate, /* bitrate/channel*/
+ chBitrate*nChannelsEff, /* overall bitrate */
nChannelsEff, /* number of channels */
sampleRate,
advancedBitsToPe,
+ dZoneQuantEnable,
invQuant
);
@@ -2545,6 +2578,7 @@ void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)],
QC_OUT* qcOut,
PSY_OUT_ELEMENT* psyOutElement[(8)],
INT CBRbitrateMode,
+ INT maxIter2ndGuess,
CHANNEL_MAPPING* cm)
{
int i;
@@ -2570,6 +2604,7 @@ void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)],
qcElement,
psyOutElement,
qcElement[i]->grantedPeCorr,
+ maxIter2ndGuess,
1, /* Process only 1 element */
i); /* Process exactly THIS element */
diff --git a/libAACenc/src/adj_thr.h b/libAACenc/src/adj_thr.h
index 69b1dcc..be68c6e 100644
--- a/libAACenc/src/adj_thr.h
+++ b/libAACenc/src/adj_thr.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -118,7 +118,8 @@ void FDKaacEnc_AdjThrInit(ADJ_THR_STATE *hAdjThr,
INT nChannelsEff,
INT sampleRate,
INT advancedBitsToPe,
- FIXP_DBL vbrQualFactor);
+ FIXP_DBL vbrQualFactor,
+ const INT dZoneQuantEnable);
void FDKaacEnc_DistributeBits(ADJ_THR_STATE *adjThrState,
@@ -140,6 +141,7 @@ void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)],
QC_OUT* qcOut,
PSY_OUT_ELEMENT* psyOutElement[(8)],
INT CBRbitrateMode,
+ INT maxIter2ndGuess,
CHANNEL_MAPPING* cm);
void FDKaacEnc_AdjThrClose(ADJ_THR_STATE** hAdjThr);
diff --git a/libAACenc/src/adj_thr_data.h b/libAACenc/src/adj_thr_data.h
index 3eb7678..7c3a191 100644
--- a/libAACenc/src/adj_thr_data.h
+++ b/libAACenc/src/adj_thr_data.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -145,6 +145,7 @@ typedef struct {
typedef struct {
BRES_PARAM bresParamLong, bresParamShort;
ATS_ELEMENT* adjThrStateElem[(8)];
+ INT maxIter2ndGuess;
} ADJ_THR_STATE;
#endif
diff --git a/libAACenc/src/bandwidth.cpp b/libAACenc/src/bandwidth.cpp
index 6fc7d87..6937362 100644
--- a/libAACenc/src/bandwidth.cpp
+++ b/libAACenc/src/bandwidth.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -127,7 +127,7 @@ static const BANDWIDTH_TAB bandWidthTable_LD_24000[] = {
{ 8000, 2000, 2000},
{12000, 2000, 2300},
{16000, 2200, 2500},
- {24000, 5650, 6400},
+ {24000, 5650, 7200},
{32000, 11600, 12000},
{40000, 12000, 16000},
{48000, 16000, 16000},
@@ -138,10 +138,10 @@ static const BANDWIDTH_TAB bandWidthTable_LD_24000[] = {
static const BANDWIDTH_TAB bandWidthTable_LD_32000[] = {
{ 8000, 2000, 2000},
{12000, 2000, 2000},
- {24000, 4250, 5200},
+ {24000, 4250, 7200},
{32000, 8400, 9000},
{40000, 9400, 11300},
- {48000, 11900, 13700},
+ {48000, 11900, 14700},
{64000, 14800, 16000},
{76000, 16000, 16000},
{360001, 16000, 16000}
diff --git a/libAACenc/src/intensity.cpp b/libAACenc/src/intensity.cpp
index 2f2109c..b45b27b 100644
--- a/libAACenc/src/intensity.cpp
+++ b/libAACenc/src/intensity.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2014 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
diff --git a/libAACenc/src/pnsparam.cpp b/libAACenc/src/pnsparam.cpp
index afc5bdd..9d59ddc 100644
--- a/libAACenc/src/pnsparam.cpp
+++ b/libAACenc/src/pnsparam.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -107,6 +107,7 @@ typedef struct {
typedef struct {
ULONG brFrom;
ULONG brTo;
+ UCHAR S16000;
UCHAR S22050;
UCHAR S24000;
UCHAR S32000;
@@ -115,25 +116,26 @@ typedef struct {
} AUTO_PNS_TAB;
static const AUTO_PNS_TAB levelTable_mono[]= {
- {0, 11999, 1, 1, 1, 1, 1,},
- {12000, 19999, 1, 1, 1, 1, 1,},
- {20000, 28999, 2, 1, 1, 1, 1,},
- {29000, 40999, 4, 4, 4, 2, 2,},
- {41000, 55999, 9, 9, 7, 7, 7,},
- {56000, 79999, 0, 0, 0, 9, 9,},
- {80000, 99999, 0, 0, 0, 0, 0,},
- {100000,999999, 0, 0, 0, 0, 0,},
+ {0, 11999, 0, 1, 1, 1, 1, 1,},
+ {12000, 19999, 0, 1, 1, 1, 1, 1,},
+ {20000, 28999, 0, 2, 1, 1, 1, 1,},
+ {29000, 40999, 0, 4, 4, 4, 2, 2,},
+ {41000, 55999, 0, 9, 9, 7, 7, 7,},
+ {56000, 61999, 0, 0, 0, 0, 9, 9,},
+ {62000, 75999, 0, 0, 0, 0, 0, 0,},
+ {76000, 92999, 0, 0, 0, 0, 0, 0,},
+ {93000, 999999, 0, 0, 0, 0, 0, 0,},
};
static const AUTO_PNS_TAB levelTable_stereo[]= {
- {0, 11999, 1, 1, 1, 1, 1,},
- {12000, 19999, 3, 1, 1, 1, 1,},
- {20000, 28999, 3, 3, 3, 2, 2,},
- {29000, 40999, 7, 6, 6, 5, 5,},
- {41000, 55999, 9, 9, 7, 7, 7,},
- {56000, 79999, 0, 0, 0, 0, 0,},
- {80000, 99999, 0, 0, 0, 0, 0,},
- {100000,999999, 0, 0, 0, 0, 0,},
+ {0, 11999, 0, 1, 1, 1, 1, 1,},
+ {12000, 19999, 0, 3, 1, 1, 1, 1,},
+ {20000, 28999, 0, 3, 3, 3, 2, 2,},
+ {29000, 40999, 0, 7, 6, 6, 5, 5,},
+ {41000, 55999, 0, 9, 9, 7, 7, 7,},
+ {56000, 79999, 0, 0, 0, 0, 0, 0,},
+ {80000, 99999, 0, 0, 0, 0, 0, 0,},
+ {100000,999999, 0, 0, 0, 0, 0, 0,},
};
@@ -160,11 +162,11 @@ static const PNS_INFO_TAB pnsInfoTab[] = {
};
static const AUTO_PNS_TAB levelTable_lowComplexity[]= {
- {0, 27999, 0, 0, 0, 0, 0,},
- {28000, 31999, 2, 2, 2, 2, 2,},
- {32000, 47999, 3, 3, 3, 3, 3,},
- {48000, 48000, 4, 4, 4, 4, 4,},
- {48001, 999999, 0, 0, 0, 0, 0,},
+ {0, 27999, 0, 0, 0, 0, 0, 0,},
+ {28000, 31999, 0, 2, 2, 2, 2, 2,},
+ {32000, 47999, 0, 3, 3, 3, 3, 3,},
+ {48000, 48000, 0, 4, 4, 4, 4, 4,},
+ {48001, 999999, 0, 0, 0, 0, 0, 0,},
};
/* conversion of old LC tuning tables to new (LD enc) structure (only entries which are actually used were converted) */
@@ -211,6 +213,7 @@ int FDKaacEnc_lookUpPnsUse (int bitRate, int sampleRate, int numChan, const int
}
switch (sampleRate) {
+ case 16000: hUsePns = levelTable[i].S16000; break;
case 22050: hUsePns = levelTable[i].S22050; break;
case 24000: hUsePns = levelTable[i].S24000; break;
case 32000: hUsePns = levelTable[i].S32000; break;
diff --git a/libAACenc/src/psy_configuration.cpp b/libAACenc/src/psy_configuration.cpp
index 4393fa1..9a72c68 100644
--- a/libAACenc/src/psy_configuration.cpp
+++ b/libAACenc/src/psy_configuration.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -634,13 +634,14 @@ AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate,
if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine)
break;
}
- psyConf->sfbActive = sfb;
+ psyConf->sfbActive = FDKmax(sfb, 1);
for (sfb = 0; sfb < psyConf->sfbCnt; sfb++){
if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLineLFE)
break;
}
psyConf->sfbActiveLFE = sfb;
+ psyConf->sfbActive = FDKmax(psyConf->sfbActive, psyConf->sfbActiveLFE);
/* calculate minSnr */
FDKaacEnc_initMinSnr(bitrate,
diff --git a/libAACenc/src/psy_main.cpp b/libAACenc/src/psy_main.cpp
index 59193c7..446c894 100644
--- a/libAACenc/src/psy_main.cpp
+++ b/libAACenc/src/psy_main.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -342,6 +342,7 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(PSY_INTERNAL *hPsy,
tnsChannels,
LONG_WINDOW,
hPsy->granuleLength,
+ isLowDelay(audioObjectType),
(syntaxFlags&AC_SBR_PRESENT)?1:0,
&(hPsy->psyConf[0].tnsConf),
&hPsy->psyConf[0],
@@ -362,6 +363,7 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(PSY_INTERNAL *hPsy,
tnsChannels,
SHORT_WINDOW,
hPsy->granuleLength,
+ isLowDelay(audioObjectType),
(syntaxFlags&AC_SBR_PRESENT)?1:0,
&hPsy->psyConf[1].tnsConf,
&hPsy->psyConf[1],
@@ -447,7 +449,7 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels,
INT totalChannels
)
{
- INT commonWindow = 1;
+ const INT commonWindow = 1;
INT maxSfbPerGroup[(2)];
INT mdctSpectrum_e;
INT ch; /* counts through channels */
@@ -621,7 +623,7 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels,
FDKmemclear(&psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset],
(windowLength[ch]-psyData[ch]->lowpassLine)*sizeof(FIXP_DBL));
- if (hPsyConfLong->filterbank != FB_LC) {
+ if ( (hPsyConfLong->filterbank != FB_LC) && (psyData[ch]->lowpassLine >= FADE_OUT_LEN) ) {
/* Do blending to reduce gibbs artifacts */
for (int i=0; i<FADE_OUT_LEN; i++) {
psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i] = fMult(psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i], fadeOutFactor[i]);
@@ -763,7 +765,8 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels,
/* Advance psychoacoustics: Tonality and TNS */
if (psyStatic[0]->isLFE) {
- tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive = 0;
+ tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] = 0;
+ tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] = 0;
}
else
{
@@ -815,15 +818,19 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels,
&hThisPsyConf[1]->tnsConf);
}
- FDK_ASSERT(commonWindow=1); /* all checks for TNS do only work for common windows (which is always set)*/
+ FDK_ASSERT(1==commonWindow); /* all checks for TNS do only work for common windows (which is always set)*/
for(w = 0; w < nWindows[0]; w++)
{
if (isShortWindow[0])
- tnsActive[w] = tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive ||
- ((channels == 2) ? tnsData[1]->dataRaw.Short.subBlockInfo[w].tnsActive : 0);
+ tnsActive[w] = tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] ||
+ tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[LOFILT] ||
+ tnsData[channels-1]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] ||
+ tnsData[channels-1]->dataRaw.Short.subBlockInfo[w].tnsActive[LOFILT];
else
- tnsActive[w] = tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive ||
- ((channels == 2) ? tnsData[1]->dataRaw.Long.subBlockInfo.tnsActive : 0);
+ tnsActive[w] = tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] ||
+ tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] ||
+ tnsData[channels-1]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] ||
+ tnsData[channels-1]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT];
}
for(ch = 0; ch < channels; ch++) {
@@ -1150,8 +1157,8 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels,
psyData[ch]->sfbMaxScaleSpec.Long,
sfbTonality[ch],
psyOutChannel[ch]->tnsInfo.order[0][0],
- tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain,
- tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive,
+ tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain[HIFILT],
+ tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT],
psyOutChannel[ch]->sfbEnergyLdData,
psyOutChannel[ch]->noiseNrg );
} /* !isLFE */
diff --git a/libAACenc/src/qc_data.h b/libAACenc/src/qc_data.h
index a9309c8..00d6090 100644
--- a/libAACenc/src/qc_data.h
+++ b/libAACenc/src/qc_data.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -269,6 +269,8 @@ typedef struct
BITCNTR_STATE *hBitCounter;
ADJ_THR_STATE *hAdjThr;
+ INT dZoneQuantEnable; /* enable dead zone quantizer */
+
} QC_STATE;
#endif /* _QC_DATA_H */
diff --git a/libAACenc/src/qc_main.cpp b/libAACenc/src/qc_main.cpp
index b74510a..9cd73f6 100644
--- a/libAACenc/src/qc_main.cpp
+++ b/libAACenc/src/qc_main.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -107,14 +107,11 @@ typedef struct {
} TAB_VBR_QUAL_FACTOR;
static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = {
- {QCDATA_BR_MODE_CBR, FL2FXCONST_DBL(0.00f)},
{QCDATA_BR_MODE_VBR_1, FL2FXCONST_DBL(0.160f)}, /* 32 kbps mono AAC-LC + SBR + PS */
{QCDATA_BR_MODE_VBR_2, FL2FXCONST_DBL(0.148f)}, /* 64 kbps stereo AAC-LC + SBR */
{QCDATA_BR_MODE_VBR_3, FL2FXCONST_DBL(0.135f)}, /* 80 - 96 kbps stereo AAC-LC */
{QCDATA_BR_MODE_VBR_4, FL2FXCONST_DBL(0.111f)}, /* 128 kbps stereo AAC-LC */
- {QCDATA_BR_MODE_VBR_5, FL2FXCONST_DBL(0.070f)}, /* 192 kbps stereo AAC-LC */
- {QCDATA_BR_MODE_SFR, FL2FXCONST_DBL(0.00f)},
- {QCDATA_BR_MODE_FF, FL2FXCONST_DBL(0.00f)}
+ {QCDATA_BR_MODE_VBR_5, FL2FXCONST_DBL(0.070f)} /* 192 kbps stereo AAC-LC */
};
static INT isConstantBitrateMode(
@@ -369,6 +366,7 @@ QCNew_bail:
AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC,
struct QC_INIT *init)
{
+ int i;
hQC->maxBitsPerFrame = init->maxBits;
hQC->minBitsPerFrame = init->minBits;
hQC->nElements = init->channelMapping->nElements;
@@ -382,7 +380,7 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC,
if ( isConstantBitrateMode(hQC->bitrateMode) ) {
INT bitresPerChannel = (hQC->bitResTotMax / init->channelMapping->nChannelsEff);
/* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir */
- hQC->bitDistributionMode = (bitresPerChannel>100) ? 0 : (bitresPerChannel>0) ? 1 : 2;
+ hQC->bitDistributionMode = (bitresPerChannel>BITRES_MIN_LD) ? 0 : (bitresPerChannel>0) ? 1 : 2;
}
else {
hQC->bitDistributionMode = 0; /* full bitreservoir */
@@ -399,25 +397,22 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC,
(init->averageBits/init->nSubFrames) - hQC->globHdrBits,
hQC->maxBitsPerFrame/init->channelMapping->nChannelsEff);
- switch(hQC->bitrateMode){
- case QCDATA_BR_MODE_CBR:
- case QCDATA_BR_MODE_VBR_1:
- case QCDATA_BR_MODE_VBR_2:
- case QCDATA_BR_MODE_VBR_3:
- case QCDATA_BR_MODE_VBR_4:
- case QCDATA_BR_MODE_VBR_5:
- case QCDATA_BR_MODE_SFR:
- case QCDATA_BR_MODE_FF:
- if((int)hQC->bitrateMode < (int)(sizeof(tableVbrQualFactor)/sizeof(TAB_VBR_QUAL_FACTOR))){
- hQC->vbrQualFactor = (FIXP_DBL)tableVbrQualFactor[hQC->bitrateMode].vbrQualFactor;
- } else {
- hQC->vbrQualFactor = FL2FXCONST_DBL(0.f); /* default setting */
- }
- break;
- case QCDATA_BR_MODE_INVALID:
- default:
- hQC->vbrQualFactor = FL2FXCONST_DBL(0.f);
+ hQC->vbrQualFactor = FL2FXCONST_DBL(0.f);
+ for (i=0; i<(int)(sizeof(tableVbrQualFactor)/sizeof(TAB_VBR_QUAL_FACTOR)); i++) {
+ if (hQC->bitrateMode==tableVbrQualFactor[i].bitrateMode) {
+ hQC->vbrQualFactor = (FIXP_DBL)tableVbrQualFactor[i].vbrQualFactor;
break;
+ }
+ }
+
+ if (init->channelMapping->nChannelsEff == 1 &&
+ (init->bitrate / init->channelMapping->nChannelsEff) < 32000 &&
+ init->advancedBitsToPe != 0
+ )
+ {
+ hQC->dZoneQuantEnable = 1;
+ } else {
+ hQC->dZoneQuantEnable = 0;
}
FDKaacEnc_AdjThrInit(
@@ -429,7 +424,8 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC,
init->channelMapping->nChannelsEff,
init->sampleRate, /* output sample rate */
init->advancedBitsToPe, /* if set, calc bits2PE factor depending on samplerate */
- hQC->vbrQualFactor
+ hQC->vbrQualFactor,
+ hQC->dZoneQuantEnable
);
return AAC_ENC_OK;
@@ -892,6 +888,7 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC,
qcOut[c],
psyOut[c]->psyOutElement,
isConstantBitrateMode(hQC->bitrateMode),
+ hQC->hAdjThr->maxIter2ndGuess,
cm);
} /* -end- sub frame counter */
@@ -919,6 +916,7 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC,
FDKaacEnc_EstimateScaleFactors(psyOut[c]->psyOutElement[i]->psyOutChannel,
qcElement[c][i]->qcOutChannel,
hQC->invQuant,
+ hQC->dZoneQuantEnable,
cm->elInfo[i].nChannelsInEl);
@@ -1013,7 +1011,8 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC,
qcOutCh->mdctSpectrum,
qcOutCh->globalGain,
qcOutCh->scf,
- qcOutCh->quantSpec) ;
+ qcOutCh->quantSpec,
+ hQC->dZoneQuantEnable);
/*-------------------------------------------- */
if (FDKaacEnc_calcMaxValueInSfb(psyOutCh->sfbCnt,
@@ -1263,6 +1262,8 @@ AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm,
case QCDATA_BR_MODE_VBR_4:
case QCDATA_BR_MODE_VBR_5:
qcOut[0]->totFillBits = (qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits)&7; /* precalculate alignment bits */
+ qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + qcOut[0]->globalExtBits;
+ qcOut[0]->totFillBits += ( fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7;
break;
case QCDATA_BR_MODE_CBR:
@@ -1272,6 +1273,8 @@ AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm,
/* processing fill-bits */
INT deltaBitRes = qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits ;
qcOut[0]->totFillBits = fixMax((deltaBitRes&7), (deltaBitRes - (fixMax(0,bitResSpace-7)&~7)));
+ qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + qcOut[0]->globalExtBits;
+ qcOut[0]->totFillBits += ( fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7;
break;
} /* switch (qcKernel->bitrateMode) */
diff --git a/libAACenc/src/quantize.cpp b/libAACenc/src/quantize.cpp
index 5380e35..a74da0e 100644
--- a/libAACenc/src/quantize.cpp
+++ b/libAACenc/src/quantize.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -104,13 +104,19 @@ amm-info@iis.fraunhofer.de
static void FDKaacEnc_quantizeLines(INT gain,
INT noOfLines,
FIXP_DBL *mdctSpectrum,
- SHORT *quaSpectrum)
+ SHORT *quaSpectrum,
+ INT dZoneQuantEnable)
{
int line;
- FIXP_DBL k = FL2FXCONST_DBL(-0.0946f + 0.5f)>>16;
+ FIXP_DBL k = FL2FXCONST_DBL(0.0f);
FIXP_QTD quantizer = FDKaacEnc_quantTableQ[(-gain)&3];
INT quantizershift = ((-gain)>>2)+1;
+ const INT kShift=16;
+ if (dZoneQuantEnable)
+ k = FL2FXCONST_DBL(0.23f)>>kShift;
+ else
+ k = FL2FXCONST_DBL(-0.0946f + 0.5f)>>kShift;
for (line = 0; line < noOfLines; line++)
{
@@ -263,7 +269,8 @@ void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
FIXP_DBL *mdctSpectrum,
INT globalGain,
INT *scalefactors,
- SHORT *quantizedSpectrum)
+ SHORT *quantizedSpectrum,
+ INT dZoneQuantEnable)
{
INT sfbOffs,sfb;
@@ -280,7 +287,8 @@ void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
FDKaacEnc_quantizeLines(globalGain - scalefactor, /* QSS */
sfbOffset[sfbOffs+sfb+1] - sfbOffset[sfbOffs+sfb],
mdctSpectrum + sfbOffset[sfbOffs+sfb],
- quantizedSpectrum + sfbOffset[sfbOffs+sfb]);
+ quantizedSpectrum + sfbOffset[sfbOffs+sfb],
+ dZoneQuantEnable);
}
}
@@ -296,7 +304,8 @@ void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum,
SHORT *quantSpectrum,
INT noOfLines,
- INT gain
+ INT gain,
+ INT dZoneQuantEnable
)
{
INT i,scale;
@@ -311,7 +320,8 @@ FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum,
FDKaacEnc_quantizeLines(gain,
1,
&mdctSpectrum[i],
- &quantSpectrum[i]);
+ &quantSpectrum[i],
+ dZoneQuantEnable);
if (fAbs(quantSpectrum[i])>MAX_QUANT) {
return FL2FXCONST_DBL(0.0f);
diff --git a/libAACenc/src/quantize.h b/libAACenc/src/quantize.h
index 975b98e..16d3d4e 100644
--- a/libAACenc/src/quantize.h
+++ b/libAACenc/src/quantize.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -102,12 +102,14 @@ void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
INT sfbPerGroup,
INT *sfbOffset, FIXP_DBL *mdctSpectrum,
INT globalGain, INT *scalefactors,
- SHORT *quantizedSpectrum);
+ SHORT *quantizedSpectrum,
+ INT dZoneQuantEnable);
FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum,
SHORT *quantSpectrum,
INT noOfLines,
- INT gain);
+ INT gain,
+ INT dZoneQuantEnable);
void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum,
SHORT *quantSpectrum,
diff --git a/libAACenc/src/sf_estim.cpp b/libAACenc/src/sf_estim.cpp
index 72b75a6..1cb243b 100644
--- a/libAACenc/src/sf_estim.cpp
+++ b/libAACenc/src/sf_estim.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -363,7 +363,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
INT scf,
INT minScf,
FIXP_DBL *distLdData,
- INT *minScfCalculated
+ INT *minScfCalculated,
+ INT dZoneQuantEnable
)
{
FIXP_DBL sfbDistLdData;
@@ -375,7 +376,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
quantSpec,
sfbWidth,
- scf);
+ scf,
+ dZoneQuantEnable);
*minScfCalculated = scf;
/* nmr > 1.25 -> try to improve nmr */
if (sfbDistLdData > (threshLdData-distFactorLdData)) {
@@ -390,7 +392,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
quantSpecTmp,
sfbWidth,
- scf);
+ scf,
+ dZoneQuantEnable);
if (sfbDistLdData < sfbDistBestLdData) {
scfBest = scf;
@@ -408,7 +411,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
quantSpecTmp,
sfbWidth,
- scf);
+ scf,
+ dZoneQuantEnable);
if (sfbDistLdData < sfbDistBestLdData) {
scfBest = scf;
@@ -429,7 +433,8 @@ static INT FDKaacEnc_improveScf(FIXP_DBL *spec,
sfbDistLdData = FDKaacEnc_calcSfbDist(spec,
quantSpecTmp,
sfbWidth,
- scf);
+ scf,
+ dZoneQuantEnable);
if (sfbDistLdData < sfbDistAllowedLdData) {
*minScfCalculated = scfBest+1;
@@ -454,6 +459,7 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,
QC_OUT_CHANNEL *qcOutChannel,
SHORT *quantSpec,
SHORT *quantSpecTmp,
+ INT dZoneQuantEnable,
INT *scf,
INT *minScf,
FIXP_DBL *sfbDist,
@@ -570,7 +576,8 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan,
sfbDistNew = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs,
quantSpecTmp+sfbOffs,
sfbWidth,
- scfAct);
+ scfAct,
+ dZoneQuantEnable);
if (sfbDistNew < sfbDist[sfbAct]) {
/* success, replace scf by new one */
@@ -629,6 +636,7 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan,
QC_OUT_CHANNEL *qcOutChannel,
SHORT *quantSpec,
SHORT *quantSpecTmp,
+ INT dZoneQuantEnable,
INT *scf,
INT *minScf,
FIXP_DBL *sfbDist,
@@ -724,7 +732,8 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan,
sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs,
quantSpecTmp+sfbOffs,
sfbWidth,
- scfAct);
+ scfAct,
+ dZoneQuantEnable);
if (sfbDistNew[sfb] >qcOutChannel->sfbThresholdLdData[sfb]) {
/* no improvement, skip further dist. calculations */
@@ -768,6 +777,7 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh
QC_OUT_CHANNEL *qcOutChannel,
SHORT *quantSpec,
SHORT *quantSpecTmp,
+ INT dZoneQuantEnable,
INT *scf,
INT *minScf,
FIXP_DBL *sfbDist,
@@ -883,7 +893,8 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh
sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb],
quantSpecTmp+sfbOffs[sfb],
sfbOffs[sfb+1]-sfbOffs[sfb],
- scfNew);
+ scfNew,
+ dZoneQuantEnable);
if (sfbDistNew[sfb] > sfbDistMax[sfb]) {
/* no improvement, skip further dist. calculations */
@@ -963,7 +974,8 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh
sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb],
quantSpecTmp+sfbOffs[sfb],
sfbOffs[sfb+1]-sfbOffs[sfb],
- scfNew);
+ scfNew,
+ dZoneQuantEnable);
if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) {
/* no improvement, skip further dist. calculations */
@@ -1058,7 +1070,8 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel,
INT *RESTRICT globalGain,
FIXP_DBL *RESTRICT sfbFormFactorLdData
,const INT invQuant,
- SHORT *RESTRICT quantSpec
+ SHORT *RESTRICT quantSpec,
+ const INT dZoneQuantEnable
)
{
INT i, j, sfb, sfbOffs;
@@ -1160,7 +1173,8 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel,
quantSpecTmp+psyOutChannel->sfbOffsets[sfbOffs+sfb],
psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb],
threshLdData, scfInt, minSfMaxQuant[sfbOffs+sfb],
- &sfbDistLdData[sfbOffs+sfb], &minScfCalculated[sfbOffs+sfb]
+ &sfbDistLdData[sfbOffs+sfb], &minScfCalculated[sfbOffs+sfb],
+ dZoneQuantEnable
);
}
scf[sfbOffs+sfb] = scfInt;
@@ -1187,20 +1201,32 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel,
sfbNRelevantLines);
- FDKaacEnc_assimilateSingleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, scf,
+ FDKaacEnc_assimilateSingleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
+ dZoneQuantEnable,
+ scf,
minSfMaxQuant, sfbDistLdData, sfbConstPePart,
sfbFormFactorLdData, sfbNRelevantLines, minScfCalculated, 1);
+ if(invQuant > 1) {
+ FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
+ dZoneQuantEnable,
+ scf,
+ minSfMaxQuant, sfbDistLdData, sfbConstPePart,
+ sfbFormFactorLdData, sfbNRelevantLines);
- FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, scf,
- minSfMaxQuant, sfbDistLdData, sfbConstPePart,
- sfbFormFactorLdData, sfbNRelevantLines);
-
+ FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
+ dZoneQuantEnable,
+ scf,
+ minSfMaxQuant, sfbDistLdData, sfbConstPePart,
+ sfbFormFactorLdData, sfbNRelevantLines);
- FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, scf,
- minSfMaxQuant, sfbDistLdData, sfbConstPePart,
- sfbFormFactorLdData, sfbNRelevantLines);
+ FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp,
+ dZoneQuantEnable,
+ scf,
+ minSfMaxQuant, sfbDistLdData, sfbConstPePart,
+ sfbFormFactorLdData, sfbNRelevantLines);
+ }
}
@@ -1223,7 +1249,8 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel,
FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+psyOutChannel->sfbOffsets[sfbOffs+sfb],
quantSpec+psyOutChannel->sfbOffsets[sfbOffs+sfb],
psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb],
- scf[sfbOffs+sfb]
+ scf[sfbOffs+sfb],
+ dZoneQuantEnable
);
}
}
@@ -1281,6 +1308,7 @@ void
FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
QC_OUT_CHANNEL* qcOutChannel[],
const int invQuant,
+ const INT dZoneQuantEnable,
const int nChannels)
{
int ch;
@@ -1293,7 +1321,8 @@ FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
&qcOutChannel[ch]->globalGain,
qcOutChannel[ch]->sfbFormFactorLdData
,invQuant,
- qcOutChannel[ch]->quantSpec
+ qcOutChannel[ch]->quantSpec,
+ dZoneQuantEnable
);
}
diff --git a/libAACenc/src/sf_estim.h b/libAACenc/src/sf_estim.h
index b5ac000..ef8d366 100644
--- a/libAACenc/src/sf_estim.h
+++ b/libAACenc/src/sf_estim.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -110,6 +110,7 @@ void
FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[],
QC_OUT_CHANNEL* qcOutChannel[],
const int invQuant,
+ const INT dZoneQuantEnable,
const int nChannels);
diff --git a/libAACenc/src/tns_func.h b/libAACenc/src/tns_func.h
index 6ee0edb..5e5265d 100644
--- a/libAACenc/src/tns_func.h
+++ b/libAACenc/src/tns_func.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -100,6 +100,7 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitrate,
INT channels,
INT blocktype,
INT granuleLength,
+ INT isLowDelay,
INT ldSbrPresent,
TNS_CONFIG *tnsConfig,
PSY_CONFIGURATION *psyConfig,
diff --git a/libFDK/include/fixpoint_math.h b/libFDK/include/fixpoint_math.h
index fcc6b5a..0d50f0a 100644
--- a/libFDK/include/fixpoint_math.h
+++ b/libFDK/include/fixpoint_math.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2014 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -94,6 +94,35 @@ amm-info@iis.fraunhofer.de
#include "common_fix.h"
+#if !defined(FUNCTION_fIsLessThan)
+/**
+ * \brief Compares two fixpoint values incl. scaling.
+ * \param a_m mantissa of the first input value.
+ * \param a_e exponent of the first input value.
+ * \param b_m mantissa of the second input value.
+ * \param b_e exponent of the second input value.
+ * \return non-zero if (a_m*2^a_e) < (b_m*2^b_e), 0 otherwise
+ */
+FDK_INLINE INT fIsLessThan(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e)
+{
+ if (a_e > b_e) {
+ return (b_m >> fMin(a_e-b_e, DFRACT_BITS-1) > a_m);
+ } else {
+ return (a_m >> fMin(b_e-a_e, DFRACT_BITS-1) < b_m);
+ }
+}
+
+FDK_INLINE INT fIsLessThan(FIXP_SGL a_m, INT a_e, FIXP_SGL b_m, INT b_e)
+{
+ if (a_e > b_e) {
+ return (b_m >> fMin(a_e-b_e, FRACT_BITS-1) > a_m);
+ } else {
+ return (a_m >> fMin(b_e-a_e, FRACT_BITS-1) < b_m);
+ }
+}
+#endif
+
+
#define LD_DATA_SCALING (64.0f)
#define LD_DATA_SHIFT 6 /* pow(2, LD_DATA_SHIFT) = LD_DATA_SCALING */
diff --git a/libFDK/src/FDK_core.cpp b/libFDK/src/FDK_core.cpp
index a706eb0..1d8ac7b 100644
--- a/libFDK/src/FDK_core.cpp
+++ b/libFDK/src/FDK_core.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -93,7 +93,7 @@ amm-info@iis.fraunhofer.de
/* FDK tools library info */
#define FDK_TOOLS_LIB_VL0 2
#define FDK_TOOLS_LIB_VL1 3
-#define FDK_TOOLS_LIB_VL2 2
+#define FDK_TOOLS_LIB_VL2 6
#define FDK_TOOLS_LIB_TITLE "FDK Tools"
#ifdef __ANDROID__
#define FDK_TOOLS_LIB_BUILD_DATE ""
diff --git a/libFDK/src/FDK_tools_rom.cpp b/libFDK/src/FDK_tools_rom.cpp
index cfc0a2e..29e37f2 100644
--- a/libFDK/src/FDK_tools_rom.cpp
+++ b/libFDK/src/FDK_tools_rom.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -2039,19 +2039,6 @@ static const element_list_t node_aac_cpe = {
{ &node_aac_cpe0, &node_aac_cpe1 }
};
-#define el_mpegsres_sce &el_aac_sce[2]
-
-static const element_list_t node_mpegsres_sce = {
- el_mpegsres_sce,
- { NULL, NULL }
-};
-
-static const element_list_t node_mpegsres_cpe = {
- el_aac_cpe1,
- { NULL, NULL }
-};
-
-
/*
* AOT C- {17,23}
* epConfig = 0,1
@@ -2249,7 +2236,7 @@ static const rbd_id_t el_aac_cpe1_epc1[] = {
ics_info,
ms,
ltp_data_present,
- ltp_data,
+ /* ltp_data, */
global_gain,
section_data,
scale_factor_data,
@@ -2260,7 +2247,7 @@ static const rbd_id_t el_aac_cpe1_epc1[] = {
next_channel,
ltp_data_present,
- ltp_data,
+ /* ltp_data, */
global_gain,
section_data,
scale_factor_data,
@@ -2303,7 +2290,178 @@ static const element_list_t node_aac_cpe_epc1 = {
{ &node_aac_cpe0_epc1, &node_aac_cpe1_epc1 }
};
+/*
+ * AOT = 20
+ * epConfig = 0
+ */
+static const rbd_id_t el_scal_sce_epc0[] = {
+ ics_info, /* ESC 1 */
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ esc2_rvlc, /* ESC 2 */
+ tns_data, /* ESC 3 */
+ spectral_data, /* ESC 4 */
+ end_of_sequence
+};
+
+static const struct element_list node_scal_sce_epc0 = {
+ el_scal_sce_epc0,
+ { NULL, NULL }
+};
+
+static const rbd_id_t el_scal_cpe_epc0[] = {
+ ics_info, /* ESC 0 */
+ ms,
+ tns_data_present, /* ESC 1 (ch 0) */
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ esc2_rvlc, /* ESC 2 (ch 0) */
+ tns_data, /* ESC 3 (ch 0) */
+ spectral_data, /* ESC 4 (ch 0) */
+ next_channel,
+ tns_data_present, /* ESC 1 (ch 1) */
+ ltp_data_present,
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ esc2_rvlc, /* ESC 2 (ch 1) */
+ tns_data, /* ESC 3 (ch 1) */
+ spectral_data, /* ESC 4 (ch 1) */
+ end_of_sequence
+};
+
+static const struct element_list node_scal_cpe_epc0 = {
+ el_scal_cpe_epc0,
+ { NULL, NULL }
+};
+
+/*
+ * AOT = 20
+ * epConfig = 1
+ */
+static const rbd_id_t el_scal_sce_epc1[] = {
+ ics_info,
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ tns_data,
+ spectral_data,
+ end_of_sequence
+};
+
+static const struct element_list node_scal_sce_epc1 = {
+ el_scal_sce_epc1,
+ { NULL, NULL }
+};
+
+static const rbd_id_t el_scal_cpe_epc1[] = {
+ ics_info,
+ ms,
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ next_channel,
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ next_channel,
+ tns_data,
+ next_channel,
+ tns_data,
+ next_channel,
+ spectral_data,
+ next_channel,
+ spectral_data,
+ end_of_sequence
+};
+
+static const struct element_list node_scal_cpe_epc1 = {
+ el_scal_cpe_epc1,
+ { NULL, NULL }
+};
+
+/*
+ * Pseudo AOT for DRM/DRM+ (similar to AOT 20)
+ * Derived from epConfig = 1
+ */
+static const rbd_id_t el_drm_sce[] = {
+ drmcrc_start_reg,
+ ics_info,
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ tns_data,
+ drmcrc_end_reg,
+ spectral_data,
+ end_of_sequence
+};
+
+static const struct element_list node_drm_sce = {
+ el_drm_sce,
+ { NULL, NULL }
+};
+
+static const rbd_id_t el_drm_cpe[] = {
+ drmcrc_start_reg,
+ ics_info,
+ ms,
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ next_channel,
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ next_channel,
+ tns_data,
+ next_channel,
+ tns_data,
+ drmcrc_end_reg,
+ next_channel,
+ spectral_data,
+ next_channel,
+ spectral_data,
+ end_of_sequence
+};
+static const struct element_list node_drm_cpe = {
+ el_drm_cpe,
+ { NULL, NULL }
+};
/*
* AOT = 39
@@ -2418,6 +2576,19 @@ const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epCo
return &node_aac_cpe_epc1;
}
break;
+ case AOT_ER_AAC_SCAL:
+ if (nChannels == 1) {
+ if (epConfig <= 0)
+ return &node_scal_sce_epc0;
+ else
+ return &node_scal_sce_epc1;
+ } else {
+ if (epConfig <= 0)
+ return &node_scal_cpe_epc0;
+ else
+ return &node_scal_cpe_epc1;
+ }
+ break;
case AOT_ER_AAC_ELD:
if (nChannels == 1) {
if (epConfig <= 0)
@@ -2430,11 +2601,14 @@ const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epCo
else
return &node_eld_cpe_epc1;
}
- case AOT_MPEGS_RESIDUALS:
+ case AOT_DRM_AAC:
+ case AOT_DRM_SBR:
+ case AOT_DRM_MPEG_PS:
+ FDK_ASSERT(epConfig == 1);
if (nChannels == 1) {
- return &node_mpegsres_sce;
+ return &node_drm_sce;
} else {
- return &node_mpegsres_cpe;
+ return &node_drm_cpe;
}
break;
default:
diff --git a/libFDK/src/arm/qmf_arm.cpp b/libFDK/src/arm/qmf_arm.cpp
index 0c0ce80..fbeebfb 100644
--- a/libFDK/src/arm/qmf_arm.cpp
+++ b/libFDK/src/arm/qmf_arm.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -482,42 +482,42 @@ static void qmfSynPrototypeFirSlot1_filter(FIXP_QMF *RESTRICT realSlot,
B = p_flt[4]; /* Bottom=[8] Top=[9] */
A = p_fltm[3]; /* Bottom=[316] Top=[317] */
sta0 = sta[0]; /* save state[0] */
- *sta++ = SMLAWT( sta[1], imag, B ); /* index=9...........319 */
- *sta++ = SMLAWB( sta[1], real, A ); /* index=316...........6 */
- *sta++ = SMLAWB( sta[1], imag, B ); /* index=8,18, ...318 */
+ sta[0] = SMLAWT( sta[1], imag, B ); sta++; /* index=9...........319 */
+ sta[0] = SMLAWB( sta[1], real, A ); sta++; /* index=316...........6 */
+ sta[0] = SMLAWB( sta[1], imag, B ); sta++; /* index=8,18, ...318 */
B = p_flt[3]; /* Bottom=[6] Top=[7] */
- *sta++ = SMLAWT( sta[1], real, A ); /* index=317...........7 */
+ sta[0] = SMLAWT( sta[1], real, A ); sta++; /* index=317...........7 */
A = p_fltm[4]; /* Bottom=[318] Top=[319] */
- *sta++ = SMLAWT( sta[1], imag, B ); /* index=7...........317 */
- *sta++ = SMLAWB( sta[1], real, A ); /* index=318...........8 */
- *sta++ = SMLAWB( sta[1], imag, B ); /* index=6...........316 */
+ sta[0] = SMLAWT( sta[1], imag, B ); sta++; /* index=7...........317 */
+ sta[0] = SMLAWB( sta[1], real, A ); sta++; /* index=318...........8 */
+ sta[0] = SMLAWB( sta[1], imag, B ); sta++; /* index=6...........316 */
B = p_flt[2]; /* Bottom=[X] Top=[5] */
- *sta++ = SMLAWT( sta[1], real, A ); /* index=9...........319 */
+ sta[0] = SMLAWT( sta[1], real, A ); sta++; /* index=9...........319 */
A = p_fltm[2]; /* Bottom=[X] Top=[315] */
- *sta++ = SMULWT( imag, B ); /* index=5,15, ... 315 */
+ sta[0] = SMULWT( imag, B ); sta++; /* index=5,15, ... 315 */
result = SMLAWT( sta0, real, A ); /* index=315...........5 */
- *pMyTimeOut++ = result;
+ pMyTimeOut[0] = result; pMyTimeOut++;
real = *--realSlot;
imag = *--imagSlot;
A = p_fltm[0]; /* Bottom=[310] Top=[311] */
B = p_flt[7]; /* Bottom=[14] Top=[15] */
result = SMLAWB( sta[0], real, A ); /* index=310...........0 */
- *sta++ = SMLAWB( sta[1], imag, B ); /* index=14..........324 */
- *pMyTimeOut++ = result;
+ sta[0] = SMLAWB( sta[1], imag, B ); sta++; /* index=14..........324 */
+ pMyTimeOut[0] = result; pMyTimeOut++;
B = p_flt[6]; /* Bottom=[12] Top=[13] */
- *sta++ = SMLAWT( sta[1], real, A ); /* index=311...........1 */
+ sta[0] = SMLAWT( sta[1], real, A ); sta++; /* index=311...........1 */
A = p_fltm[1]; /* Bottom=[312] Top=[313] */
- *sta++ = SMLAWT( sta[1], imag, B ); /* index=13..........323 */
- *sta++ = SMLAWB( sta[1], real, A ); /* index=312...........2 */
- *sta++ = SMLAWB( sta[1], imag, B ); /* index=12..........322 */
- *sta++ = SMLAWT( sta[1], real, A ); /* index=313...........3 */
+ sta[0] = SMLAWT( sta[1], imag, B ); sta++; /* index=13..........323 */
+ sta[0] = SMLAWB( sta[1], real, A ); sta++; /* index=312...........2 */
+ sta[0] = SMLAWB( sta[1], imag, B ); sta++; /* index=12..........322 */
+ sta[0] = SMLAWT( sta[1], real, A ); sta++; /* index=313...........3 */
A = p_fltm[2]; /* Bottom=[314] Top=[315] */
B = p_flt[5]; /* Bottom=[10] Top=[11] */
- *sta++ = SMLAWT( sta[1], imag, B ); /* index=11..........321 */
- *sta++ = SMLAWB( sta[1], real, A ); /* index=314...........4 */
- *sta++ = SMULWB( imag, B ); /* index=10..........320 */
+ sta[0] = SMLAWT( sta[1], imag, B ); sta++; /* index=11..........321 */
+ sta[0] = SMLAWB( sta[1], real, A ); sta++; /* index=314...........4 */
+ sta[0] = SMULWB( imag, B ); sta++; /* index=10..........320 */
p_flt += 5;
@@ -566,21 +566,21 @@ INT qmfSynPrototypeFirSlot2(
A = p_fltm[0]; /* Bottom=[310] Top=[311] */
B = p_flt[7]; /* Bottom=[14] Top=[15] */
result = SMLAWB( sta[0], real, A ); /* index=310...........0 */
- *sta++ = SMLAWB( sta[1], imag, B ); /* index=14..........324 */
+ sta[0] = SMLAWB( sta[1], imag, B ); sta++; /* index=14..........324 */
B = p_flt[6]; /* Bottom=[12] Top=[13] */
- *sta++ = SMLAWT( sta[1], real, A ); /* index=311...........1 */
+ sta[0] = SMLAWT( sta[1], real, A ); sta++; /* index=311...........1 */
A = p_fltm[1]; /* Bottom=[312] Top=[313] */
- *sta++ = SMLAWT( sta[1], imag, B ); /* index=13..........323 */
- *sta++ = SMLAWB( sta[1], real, A ); /* index=312...........2 */
- *sta++ = SMLAWB( sta[1], imag, B ); /* index=12..........322 */
- *sta++ = SMLAWT( sta[1], real, A ); /* index=313...........3 */
+ sta[0] = SMLAWT( sta[1], imag, B ); sta++; /* index=13..........323 */
+ sta[0] = SMLAWB( sta[1], real, A ); sta++; /* index=312...........2 */
+ sta[0] = SMLAWB( sta[1], imag, B ); sta++; /* index=12..........322 */
+ sta[0] = SMLAWT( sta[1], real, A ); sta++; /* index=313...........3 */
A = p_fltm[2]; /* Bottom=[314] Top=[315] */
B = p_flt[5]; /* Bottom=[10] Top=[11] */
- *sta++ = SMLAWT( sta[1], imag, B ); /* index=11..........321 */
- *sta++ = SMLAWB( sta[1], real, A ); /* index=314...........4 */
- *sta++ = SMULWB( imag, B ); /* index=10..........320 */
+ sta[0] = SMLAWT( sta[1], imag, B ); sta++; /* index=11..........321 */
+ sta[0] = SMLAWB( sta[1], real, A ); sta++; /* index=314...........4 */
+ sta[0] = SMULWB( imag, B ); sta++; /* index=10..........320 */
- *pMyTimeOut++ = result;
+ pMyTimeOut[0] = result; pMyTimeOut++;
p_fltm -= 5;
p_flt += 5;
@@ -610,8 +610,8 @@ INT qmfSynPrototypeFirSlot2(
{
FIXP_DBL result1, result2;
- result1 = *pMyTimeOut++;
- result2 = *pMyTimeOut++;
+ result1 = pMyTimeOut[0]; pMyTimeOut++;
+ result2 = pMyTimeOut[0]; pMyTimeOut++;
result1 = fMult(result1,gain);
timeOut -= stride;
@@ -635,8 +635,8 @@ INT qmfSynPrototypeFirSlot2(
timeOut[0] = result2 << scale;
#endif
- result1 = *pMyTimeOut++;
- result2 = *pMyTimeOut++;
+ result1 = pMyTimeOut[0]; pMyTimeOut++;
+ result2 = pMyTimeOut[0]; pMyTimeOut++;
result1 = fMult(result1,gain);
timeOut -= stride;
@@ -666,8 +666,8 @@ INT qmfSynPrototypeFirSlot2(
for (no_channels>>=2; no_channels--;)
{
FIXP_DBL result1, result2;
- result1 = *pMyTimeOut++;
- result2 = *pMyTimeOut++;
+ result1 = pMyTimeOut[0]; pMyTimeOut++;
+ result2 = pMyTimeOut[0]; pMyTimeOut++;
timeOut -= stride;
if (result1 < 0) result1 += add_neg;
if (result1 < max_neg) result1 = max_neg;
@@ -688,8 +688,8 @@ INT qmfSynPrototypeFirSlot2(
timeOut[0] = result2 << scale;
#endif
- result1 = *pMyTimeOut++;
- result2 = *pMyTimeOut++;
+ result1 = pMyTimeOut[0]; pMyTimeOut++;
+ result2 = pMyTimeOut[0]; pMyTimeOut++;
timeOut -= stride;
if (result1 < 0) result1 += add_neg;
if (result1 < max_neg) result1 = max_neg;
diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp
index bae271e..96a1b35 100644
--- a/libMpegTPDec/src/tpdec_asc.cpp
+++ b/libMpegTPDec/src/tpdec_asc.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -1126,6 +1126,8 @@ TRANSPORTDEC_ERROR EldSpecificConfig_Parse(
if ( 0 != ld_sbr_header(asc, hBs, cb) ) {
return TRANSPORTDEC_PARSE_ERROR;
}
+ } else {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
}
}
esc->m_useLdQmfTimeAlign = 0;
@@ -1146,7 +1148,7 @@ TRANSPORTDEC_ERROR EldSpecificConfig_Parse(
switch (eldExtType) {
default:
- for(cnt=0; cnt<len; cnt++) {
+ for(cnt=0; cnt<eldExtLen; cnt++) {
FDKreadBits(hBs, 8 );
}
break;
@@ -1372,4 +1374,133 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
return (ErrorStatus);
}
+TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(
+ CSAudioSpecificConfig *self,
+ HANDLE_FDK_BITSTREAM bs
+ )
+{
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+
+ AudioSpecificConfig_Init(self);
+
+ if ((INT)FDKgetValidBits(bs) < 20) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ else {
+ /* DRM - Audio information data entity - type 9
+ - Short Id 2 bits
+ - Stream Id 2 bits
+ - audio coding 2 bits
+ - SBR flag 1 bit
+ - audio mode 2 bits
+ - audio sampling rate 3 bits
+ - text flag 1 bit
+ - enhancement flag 1 bit
+ - coder field 5 bits
+ - rfa 1 bit */
+
+ int audioCoding, audioMode, cSamplingFreq, coderField, sfIdx, sbrFlag;
+
+ /* Read the SDC field */
+ FDKreadBits(bs,4); /* Short and Stream Id */
+
+ audioCoding = FDKreadBits(bs, 2);
+ sbrFlag = FDKreadBits(bs, 1);
+ audioMode = FDKreadBits(bs, 2);
+ cSamplingFreq = FDKreadBits(bs, 3); /* audio sampling rate */
+
+ FDKreadBits(bs, 2); /* Text and enhancement flag */
+ coderField = FDKreadBits(bs, 5);
+ FDKreadBits(bs, 1); /* rfa */
+
+ /* Evaluate configuration and fill the ASC */
+ switch (cSamplingFreq) {
+ case 0: /* 8 kHz */
+ sfIdx = 11;
+ break;
+ case 1: /* 12 kHz */
+ sfIdx = 9;
+ break;
+ case 2: /* 16 kHz */
+ sfIdx = 8;
+ break;
+ case 3: /* 24 kHz */
+ sfIdx = 6;
+ break;
+ case 5: /* 48 kHz */
+ sfIdx = 3;
+ break;
+ case 4: /* reserved */
+ case 6: /* reserved */
+ case 7: /* reserved */
+ default:
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ self->m_samplingFrequencyIndex = sfIdx;
+ self->m_samplingFrequency = SamplingRateTable[sfIdx];
+
+ if ( sbrFlag ) {
+ UINT i;
+ int tmp = -1;
+ self->m_sbrPresentFlag = 1;
+ self->m_extensionAudioObjectType = AOT_SBR;
+ self->m_extensionSamplingFrequency = self->m_samplingFrequency << 1;
+ for (i=0; i<(sizeof(SamplingRateTable)/sizeof(SamplingRateTable[0])); i++){
+ if (SamplingRateTable[i] == self->m_extensionSamplingFrequency){
+ tmp = i;
+ break;
+ }
+ }
+ self->m_extensionSamplingFrequencyIndex = tmp;
+ }
+
+ switch (audioCoding) {
+ case 0: /* AAC */
+ self->m_aot = AOT_DRM_AAC ; /* Set pseudo AOT for Drm AAC */
+
+ switch (audioMode) {
+ case 1: /* parametric stereo */
+ self->m_psPresentFlag = 1;
+ case 0: /* mono */
+ self->m_channelConfiguration = 1;
+ break;
+ case 2: /* stereo */
+ self->m_channelConfiguration = 2;
+ break;
+ default:
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ self->m_vcb11Flag = 1;
+ self->m_hcrFlag = 1;
+ self->m_samplesPerFrame = 960;
+ self->m_epConfig = 1;
+ break;
+ case 1: /* CELP */
+ self->m_aot = AOT_ER_CELP;
+ self->m_channelConfiguration = 1;
+ break;
+ case 2: /* HVXC */
+ self->m_aot = AOT_ER_HVXC;
+ self->m_channelConfiguration = 1;
+ break;
+ case 3: /* reserved */
+ default:
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ self->m_aot = AOT_NONE;
+ break;
+ }
+
+ if (self->m_psPresentFlag && !self->m_sbrPresentFlag) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+bail:
+ return (ErrorStatus);
+}
diff --git a/libAACenc/src/aacenc_hcr.h b/libMpegTPDec/src/tpdec_drm.cpp
index 934247a..df319e5 100644
--- a/libAACenc/src/aacenc_hcr.h
+++ b/libMpegTPDec/src/tpdec_drm.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -81,16 +81,66 @@ www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------------------------------------- */
-/*************************** MPEG AAC Audio Encoder *************************
+/***************************** MPEG-4 AAC Decoder **************************
- Initial author: R. Boehm
- contents/description: huffman codeword reordering
- based on source from aacErrRobTrans
+ Author(s): Christian Griebel
+ Description: DRM transport stuff
******************************************************************************/
-#ifndef _AACENC_HCR
-#define _AACENC_HCR_H
+#include "tpdec_drm.h"
+
+
+#include "FDK_bitstream.h"
+
+
+
+void drmRead_CrcInit(HANDLE_DRM pDrm) /*!< pointer to drm crc info stucture */
+{
+ FDK_ASSERT(pDrm != NULL);
+
+ FDKcrcInit(&pDrm->crcInfo, 0x001d, 0xFFFF, 8);
+}
+
+int drmRead_CrcStartReg(
+ HANDLE_DRM pDrm, /*!< pointer to drm stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int mBits /*!< number of bits in crc region */
+ )
+{
+ FDK_ASSERT(pDrm != NULL);
+
+ FDKcrcReset(&pDrm->crcInfo);
+
+ pDrm->crcReadValue = FDKreadBits(hBs, 8);
+
+ return ( FDKcrcStartReg(&pDrm->crcInfo, hBs, mBits) );
+
+}
+
+void drmRead_CrcEndReg(
+ HANDLE_DRM pDrm, /*!< pointer to drm crc info stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int reg /*!< crc region */
+ )
+{
+ FDK_ASSERT(pDrm != NULL);
+
+ FDKcrcEndReg(&pDrm->crcInfo, hBs, reg);
+}
+
+TRANSPORTDEC_ERROR drmRead_CrcCheck( HANDLE_DRM pDrm )
+{
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ USHORT crc;
+
+ crc = FDKcrcGetCRC(&pDrm->crcInfo) ^ 0xFF;
+ if (crc != pDrm->crcReadValue)
+ {
+ return (TRANSPORTDEC_CRC_ERROR);
+ }
+
+ return (ErrorStatus);
+}
-#endif /* ifndef _AACENC_HCR */
diff --git a/libAACenc/src/aacenc_hcr.cpp b/libMpegTPDec/src/tpdec_drm.h
index 316623a..2161b4c 100644
--- a/libAACenc/src/aacenc_hcr.cpp
+++ b/libMpegTPDec/src/tpdec_drm.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -81,13 +81,114 @@ www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------------------------------------- */
-/*************************** MPEG AAC Audio Encoder *************************
+/***************************** MPEG-4 AAC Decoder **************************
- Initial author: R. Boehm
- contents/description: huffman codeword reordering
- based on source from aacErrRobTrans
+ Author(s): Josef Hoepfl
+ Description: DRM interface
******************************************************************************/
-#include "aacenc_hcr.h"
-
+#ifndef TPDEC_DRM_H
+#define TPDEC_DRM_H
+
+#include "tpdec_lib.h"
+
+
+#include "FDK_crc.h"
+
+typedef struct {
+
+ FDK_CRCINFO crcInfo; /* CRC state info */
+ USHORT crcReadValue; /* CRC value read from bitstream data */
+
+} STRUCT_DRM;
+
+typedef STRUCT_DRM *HANDLE_DRM;
+
+/*!
+ \brief Initialize DRM CRC
+
+ The function initialzes the crc buffer and the crc lookup table.
+
+ \return none
+*/
+void drmRead_CrcInit( HANDLE_DRM pDrm );
+
+/**
+ * \brief Starts CRC region with a maximum number of bits
+ * If mBits is positive zero padding will be used for CRC calculation, if there
+ * are less than mBits bits available.
+ * If mBits is negative no zero padding is done.
+ * If mBits is zero the memory for the buffer is allocated dynamically, the
+ * number of bits is not limited.
+ *
+ * \param pDrm DRM data handle
+ * \param hBs bitstream handle, on which the CRC region referes to
+ * \param mBits max number of bits in crc region to be considered
+ *
+ * \return ID for the created region, -1 in case of an error
+ */
+int drmRead_CrcStartReg(
+ HANDLE_DRM pDrm,
+ HANDLE_FDK_BITSTREAM hBs,
+ int mBits
+ );
+
+/**
+ * \brief Ends CRC region identified by reg
+ *
+ * \param pDrm DRM data handle
+ * \param hBs bitstream handle, on which the CRC region referes to
+ * \param reg CRC regions ID returned by drmRead_CrcStartReg()
+ *
+ * \return none
+ */
+void drmRead_CrcEndReg(
+ HANDLE_DRM pDrm,
+ HANDLE_FDK_BITSTREAM hBs,
+ int reg
+ );
+
+/**
+ * \brief Check CRC
+ *
+ * Checks if the currently calculated CRC matches the CRC field read from the bitstream
+ * Deletes all CRC regions.
+ *
+ * \param pDrm DRM data handle
+ *
+ * \return Returns 0 if they are identical otherwise 1
+ */
+TRANSPORTDEC_ERROR drmRead_CrcCheck( HANDLE_DRM pDrm );
+
+/**
+ * \brief Check if we have a valid DRM frame at the current bitbuffer position
+ *
+ * This function assumes enough bits in buffer for the current frame.
+ * It reads out the header bits to prepare the bitbuffer for the decode loop.
+ * In case the header bits show an invalid bitstream/frame, the whole frame is skipped.
+ *
+ * \param pDrm DRM data handle which is filled with parsed DRM header data
+ * \param bs handle of bitstream from whom the DRM header is read
+ *
+ * \return error status
+ */
+TRANSPORTDEC_ERROR drmRead_DecodeHeader(
+ HANDLE_DRM pDrm,
+ HANDLE_FDK_BITSTREAM bs
+ );
+
+/**
+ * \brief Parse a Drm specific SDC audio config from a given bitstream handle.
+ *
+ * \param pAsc A pointer to an allocated CSAudioSpecificConfig struct.
+ * \param hBs Bitstream handle.
+ *
+ * \return Total element count including all SCE, CPE and LFE.
+ */
+TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse( CSAudioSpecificConfig *pAsc,
+ HANDLE_FDK_BITSTREAM hBs );
+
+
+
+#endif /* TPDEC_DRM_H */
diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp
index 445615d..24f755b 100644
--- a/libMpegTPDec/src/tpdec_lib.cpp
+++ b/libMpegTPDec/src/tpdec_lib.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -102,6 +102,7 @@ amm-info@iis.fraunhofer.de
#include "tpdec_latm.h"
+#include "tpdec_drm.h"
#define MODULE_NAME "transportDec"
@@ -113,6 +114,7 @@ typedef union {
CLatmDemux latm;
+ STRUCT_DRM drm;
} transportdec_parser_t;
@@ -182,6 +184,9 @@ HANDLE_TRANSPORTDEC transportDec_Open( const TRANSPORT_TYPE transportFmt, const
hInput->numberOfRawDataBlocks = 0;
break;
+ case TT_DRM:
+ drmRead_CrcInit(&hInput->parser.drm);
+ break;
case TT_MP4_LATM_MCP0:
case TT_MP4_LATM_MCP1:
@@ -253,6 +258,18 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR *
}
}
break;
+ case TT_DRM:
+ fConfigFound = 1;
+ err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs);
+ if (err == TRANSPORTDEC_OK) {
+ int errC;
+
+ errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer]);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ break;
}
if (err == TRANSPORTDEC_OK && fConfigFound) {
@@ -1083,6 +1100,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c
break;
case TT_MP4_RAW:
+ case TT_DRM:
/* One Access Unit was filled into buffer.
So get the length out of the buffer. */
hTp->auLength[layer] = FDKgetValidBits(hBs);
@@ -1100,7 +1118,6 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c
}
break;
- case TT_RSVD50:
case TT_MP4_ADTS:
case TT_MP4_LOAS:
err = transportDec_readStream(hTp, layer);
@@ -1284,6 +1301,7 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info )
| CAPF_LATM
| CAPF_LOAS
| CAPF_RAWPACKETS
+ | CAPF_DRM
;
return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */
@@ -1295,6 +1313,8 @@ int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits)
switch (pTp->transportFmt) {
case TT_MP4_ADTS:
return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits);
+ case TT_DRM:
+ return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits);
default:
return 0;
}
@@ -1306,6 +1326,9 @@ void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg)
case TT_MP4_ADTS:
adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg);
break;
+ case TT_DRM:
+ drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg);
+ break;
default:
break;
}
@@ -1322,6 +1345,9 @@ TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp)
transportDec_AdjustEndOfAccessUnit(pTp);
}
return adtsRead_CrcCheck(&pTp->parser.adts);
+ case TT_DRM:
+ return drmRead_CrcCheck(&pTp->parser.drm);
+ break;
default:
return TRANSPORTDEC_OK;
}
diff --git a/libMpegTPDec/src/version b/libMpegTPDec/src/version
index fc7e5f0..75e22c9 100644
--- a/libMpegTPDec/src/version
+++ b/libMpegTPDec/src/version
@@ -2,7 +2,7 @@
/* library info */
#define TP_LIB_VL0 2
#define TP_LIB_VL1 3
-#define TP_LIB_VL2 4
+#define TP_LIB_VL2 7
#define TP_LIB_TITLE "MPEG Transport"
#ifdef __ANDROID__
#define TP_LIB_BUILD_DATE ""
diff --git a/libMpegTPEnc/src/tpenc_latm.cpp b/libMpegTPEnc/src/tpenc_latm.cpp
index 58e51ef..f292019 100644
--- a/libMpegTPEnc/src/tpenc_latm.cpp
+++ b/libMpegTPEnc/src/tpenc_latm.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -296,6 +296,7 @@ CreateStreamMuxConfig(
USHORT coreFrameOffset=0;
+ hAss->taraBufferFullness = 0xFF;
hAss->audioMuxVersionA = 0; /* for future extensions */
hAss->streamMuxConfigBits = 0;
@@ -339,13 +340,7 @@ CreateStreamMuxConfig(
hAss->streamMuxConfigBits+=1;
}
if( (useSameConfig == 0) || (transLayer==0) ) {
- UINT bits;
-
- if ( hAss->audioMuxVersion == 1 ) {
- FDKpushFor(hBs, 2); /* align to ASC, even if we do not know the length of the "ascLen" field yet */
- }
-
- bits = FDKgetValidBits( hBs );
+ const UINT alignAnchor = FDKgetValidBits(hBs);
transportEnc_writeASC(
hBs,
@@ -353,19 +348,24 @@ CreateStreamMuxConfig(
cb
);
- bits = FDKgetValidBits( hBs ) - bits;
-
if ( hAss->audioMuxVersion == 1 ) {
- FDKpushBack(hBs, bits+2);
- hAss->streamMuxConfigBits += transportEnc_LatmWriteValue( hBs, bits );
+ UINT ascLen = transportEnc_LatmWriteValue(hBs, 0);
+ FDKbyteAlign(hBs, alignAnchor);
+ ascLen = FDKgetValidBits(hBs) - alignAnchor - ascLen;
+ FDKpushBack(hBs, FDKgetValidBits(hBs) - alignAnchor);
+
+ transportEnc_LatmWriteValue(hBs, ascLen);
+
transportEnc_writeASC(
hBs,
hAss->config[prog][layer],
cb
);
+
+ FDKbyteAlign(hBs, alignAnchor); /* asc length fillbits */
}
- hAss->streamMuxConfigBits += bits; /* add asc length to smc summary */
+ hAss->streamMuxConfigBits += FDKgetValidBits(hBs) - alignAnchor; /* add asc length to smc summary */
}
transLayer++;
@@ -384,7 +384,6 @@ CreateStreamMuxConfig(
case AOT_ER_AAC_LD :
case AOT_ER_AAC_ELD :
case AOT_USAC:
- case AOT_RSVD50:
p_linfo->frameLengthType = 0;
FDKwriteBits( hBs, p_linfo->frameLengthType, 3 ); /* frameLengthType */
diff --git a/libMpegTPEnc/src/version b/libMpegTPEnc/src/version
index fc7e5f0..8742568 100644
--- a/libMpegTPEnc/src/version
+++ b/libMpegTPEnc/src/version
@@ -2,7 +2,7 @@
/* library info */
#define TP_LIB_VL0 2
#define TP_LIB_VL1 3
-#define TP_LIB_VL2 4
+#define TP_LIB_VL2 6
#define TP_LIB_TITLE "MPEG Transport"
#ifdef __ANDROID__
#define TP_LIB_BUILD_DATE ""
diff --git a/libSBRdec/include/sbrdecoder.h b/libSBRdec/include/sbrdecoder.h
index 174fb5c..3bb9ba3 100644
--- a/libSBRdec/include/sbrdecoder.h
+++ b/libSBRdec/include/sbrdecoder.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -262,6 +262,7 @@ void sbrDecoder_drcDisable ( HANDLE_SBRDECODER self,
* into *count if a payload length is given (byPayLen > 0). If no SBR payload length is
* given (bsPayLen < 0) then the bit stream position on return will be random after this
* function call in case of errors, and any further decoding will be completely pointless.
+ * This function accepts either normal ordered SBR data or reverse ordered DRM SBR data.
*
* \param self SBR decoder handle.
* \param hBs Bit stream handle as data source.
diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp
index ade57fc..fa5330a 100644
--- a/libSBRdec/src/env_calc.cpp
+++ b/libSBRdec/src/env_calc.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -151,13 +151,13 @@ typedef struct
}
ENV_CALC_NRGS;
-/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer,
+static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer,
SCHAR *filtBuffer_e,
FIXP_DBL *NrgGain,
SCHAR *NrgGain_e,
int subbands);
-/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal,
+static void calcNrgPerSubband(FIXP_DBL **analysBufferReal,
FIXP_DBL **analysBufferImag,
int lowSubband, int highSubband,
int start_pos, int next_pos,
@@ -165,7 +165,7 @@ ENV_CALC_NRGS;
FIXP_DBL *nrgEst,
SCHAR *nrgEst_e );
-/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal,
+static void calcNrgPerSfb(FIXP_DBL **analysBufferReal,
FIXP_DBL **analysBufferImag,
int nSfb,
UCHAR *freqBandTable,
@@ -174,13 +174,13 @@ ENV_CALC_NRGS;
FIXP_DBL *nrg_est,
SCHAR *nrg_est_e );
-/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c,
+static void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c,
FIXP_DBL tmpNoise, SCHAR tmpNoise_e,
UCHAR sinePresentFlag,
UCHAR sineMapped,
int noNoiseFlag);
-/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs,
+static void calcAvgGain(ENV_CALC_NRGS* nrgs,
int lowSubband,
int highSubband,
FIXP_DBL *sumRef_m,
@@ -188,7 +188,7 @@ ENV_CALC_NRGS;
FIXP_DBL *ptrAvgGain_m,
SCHAR *ptrAvgGain_e);
-/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal,
+static void adjustTimeSlot_EldGrid(FIXP_DBL *ptrReal,
ENV_CALC_NRGS* nrgs,
UCHAR *ptrHarmIndex,
int lowSubbands,
@@ -196,8 +196,17 @@ ENV_CALC_NRGS;
int scale_change,
int noNoiseFlag,
int *ptrPhaseIndex,
- int fCldfb);
-/*static*/ void adjustTimeSlotHQ(FIXP_DBL *ptrReal,
+ int scale_diff_low);
+
+static void adjustTimeSlotLC(FIXP_DBL *ptrReal,
+ ENV_CALC_NRGS* nrgs,
+ UCHAR *ptrHarmIndex,
+ int lowSubbands,
+ int noSubbands,
+ int scale_change,
+ int noNoiseFlag,
+ int *ptrPhaseIndex);
+static void adjustTimeSlotHQ(FIXP_DBL *ptrReal,
FIXP_DBL *ptrImag,
HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
ENV_CALC_NRGS* nrgs,
@@ -224,7 +233,7 @@ ENV_CALC_NRGS;
Additionally, the flags in harmFlagsPrev are being updated by this function
for the next frame.
*/
-/*static*/ void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */
+static void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */
int nSfb, /*!< Number of bands in the table */
UCHAR *addHarmonics, /*!< vector with 1 flag per sfb */
int *harmFlagsPrev, /*!< Packed 'addHarmonics' */
@@ -990,7 +999,6 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling
/* Prevent the smoothing filter from running on constant levels */
if (j-start_pos < smooth_length)
smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j-start_pos];
-
else
smooth_ratio = FL2FXCONST_SGL(0.0f);
@@ -1007,7 +1015,8 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling
}
else
{
- adjustTimeSlotLC(&analysBufferReal[j][lowSubband],
+ if (flags & SBRDEC_ELD_GRID) {
+ adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband],
pNrgs,
&h_sbr_cal_env->harmIndex,
lowSubband,
@@ -1015,7 +1024,18 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling
scale_change,
noNoiseFlag,
&h_sbr_cal_env->phaseIndex,
- (flags & SBRDEC_ELD_GRID));
+ EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale);
+ } else
+ {
+ adjustTimeSlotLC(&analysBufferReal[j][lowSubband],
+ pNrgs,
+ &h_sbr_cal_env->harmIndex,
+ lowSubband,
+ noSubbands,
+ scale_change,
+ noNoiseFlag,
+ &h_sbr_cal_env->phaseIndex);
+ }
}
} // for
@@ -1176,7 +1196,7 @@ resetSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to env
can be performed.
This function is called once for each envelope before adjusting.
*/
-/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */
+static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */
SCHAR *filtBuffer_e, /*!< exponents of bufferd gains */
FIXP_DBL *nrgGain, /*!< gains for current envelope */
SCHAR *nrgGain_e, /*!< exponents of gains for current envelope */
@@ -1331,7 +1351,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
This function is used when interpolFreq is true.
*/
-/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
+static void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
int lowSubband, /*!< Begin of the SBR frequency range */
int highSubband, /*!< High end of the SBR frequency range */
@@ -1452,7 +1472,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
This function is used when interpolFreq is false.
*/
-/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
+static void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
int nSfb, /*!< Number of scale factor bands */
UCHAR *freqBandTable, /*!< First Subband for each Sfb */
@@ -1585,7 +1605,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
The resulting energy gain is given by mantissa and exponent.
*/
-/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */
+static void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */
SCHAR nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */
ENV_CALC_NRGS* nrgs,
int i,
@@ -1689,7 +1709,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
The result is used as a relative limit for all gains within the
current "limiter band" (a certain frequency range).
*/
-/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs,
+static void calcAvgGain(ENV_CALC_NRGS* nrgs,
int lowSubband, /*!< Begin of the limiter band */
int highSubband, /*!< High end of the limiter band */
FIXP_DBL *ptrSumRef,
@@ -1728,21 +1748,101 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
*ptrSumRef_e = sumRef_e;
}
+static void adjustTimeSlot_EldGrid(
+ FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */
+ ENV_CALC_NRGS* nrgs,
+ UCHAR *ptrHarmIndex, /*!< Harmonic index */
+ int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
+ int noSubbands, /*!< Number of QMF subbands */
+ int scale_change, /*!< Number of bits to shift adjusted samples */
+ int noNoiseFlag, /*!< Flag to suppress noise addition */
+ int *ptrPhaseIndex, /*!< Start index to random number array */
+ int scale_diff_low) /*!< */
+{
+ int k;
+ FIXP_DBL signalReal, sbNoise;
+ int tone_count = 0;
+
+ FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
+ FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */
+ FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */
+
+ int phaseIndex = *ptrPhaseIndex;
+ UCHAR harmIndex = *ptrHarmIndex;
+
+ static const INT harmonicPhase [2][4] = {
+ { 1, 0, -1, 0},
+ { 0, 1, 0, -1}
+ };
+
+ static const FIXP_DBL harmonicPhaseX [2][4] = {
+ { FL2FXCONST_DBL(2.0*1.245183154539139e-001), FL2FXCONST_DBL(2.0*-1.123767859325028e-001), FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0* 1.123767859325028e-001) },
+ { FL2FXCONST_DBL(2.0*1.245183154539139e-001), FL2FXCONST_DBL(2.0* 1.123767859325028e-001), FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0*-1.123767859325028e-001) }
+ };
+
+ for (k=0; k < noSubbands; k++) {
+
+ phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
+
+ if( (pSineLevel[0] != FL2FXCONST_DBL(0.0f)) || (noNoiseFlag == 1) ){
+ sbNoise = FL2FXCONST_DBL(0.0f);
+ } else {
+ sbNoise = pNoiseLevel[0];
+ }
+
+ signalReal = fMultDiv2(*ptrReal,*pGain) << ((int)scale_change);
+
+ signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise)<<4);
+
+ signalReal += pSineLevel[0] * harmonicPhase[0][harmIndex];
+
+ *ptrReal = signalReal;
+
+ if (k == 0) {
+ *(ptrReal-1) += scaleValue(fMultDiv2(harmonicPhaseX[lowSubband&1][harmIndex], pSineLevel[0]), -scale_diff_low) ;
+ if (k < noSubbands - 1) {
+ *(ptrReal) += fMultDiv2(pSineLevel[1], harmonicPhaseX[(lowSubband+1)&1][harmIndex]);
+ }
+ }
+ if (k > 0 && k < noSubbands - 1 && tone_count < 16) {
+ *(ptrReal) += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1] [harmIndex]);
+ *(ptrReal) += fMultDiv2(pSineLevel[+ 1], harmonicPhaseX [(lowSubband+k+1)&1][harmIndex]);
+ }
+ if (k == noSubbands - 1 && tone_count < 16) {
+ if (k > 0) {
+ *(ptrReal) += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1][harmIndex]);
+ }
+ if (k + lowSubband + 1< 63) {
+ *(ptrReal+1) += fMultDiv2(pSineLevel[0], harmonicPhaseX[(lowSubband+k+1)&1][harmIndex]);
+ }
+ }
+
+ if(pSineLevel[0] != FL2FXCONST_DBL(0.0f)){
+ tone_count++;
+ }
+ ptrReal++;
+ pNoiseLevel++;
+ pGain++;
+ pSineLevel++;
+ }
+
+ *ptrHarmIndex = (harmIndex + 1) & 3;
+ *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1);
+}
/*!
\brief Amplify one timeslot of the signal with the calculated gains
and add the noisefloor.
*/
-/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */
+static void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */
ENV_CALC_NRGS* nrgs,
UCHAR *ptrHarmIndex, /*!< Harmonic index */
int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
int noSubbands, /*!< Number of QMF subbands */
int scale_change, /*!< Number of bits to shift adjusted samples */
int noNoiseFlag, /*!< Flag to suppress noise addition */
- int *ptrPhaseIndex, /*!< Start index to random number array */
- int fCldfb) /*!< CLDFB 80 flag */
+ int *ptrPhaseIndex) /*!< Start index to random number array */
{
FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */
@@ -1775,41 +1875,10 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
if (sineLevel!=FL2FXCONST_DBL(0.0f)) tone_count++;
-
else if (!noNoiseFlag)
/* Add noisefloor to the amplified signal */
signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
- if (fCldfb) {
-
- if (!(harmIndex&0x1)) {
- /* harmIndex 0,2 */
- signalReal += (harmIndex&0x2) ? -sineLevel : sineLevel;
- *ptrReal++ = signalReal;
- }
- else {
- /* harmIndex 1,3 in combination with freqInvFlag */
- int shift = (int) (scale_change+1);
- shift = (shift>=0) ? fixMin(DFRACT_BITS-1,shift) : fixMax(-(DFRACT_BITS-1),shift);
-
- FIXP_DBL tmp1 = scaleValue( fMultDiv2(C1_CLDFB, sineLevel), -shift );
-
- FIXP_DBL tmp2 = fMultDiv2(C1_CLDFB, sineLevelNext);
-
-
- /* save switch and compare operations and reduce to XOR statement */
- if ( ((harmIndex>>1)&0x1)^freqInvFlag) {
- *(ptrReal-1) += tmp1;
- signalReal -= tmp2;
- } else {
- *(ptrReal-1) -= tmp1;
- signalReal += tmp2;
- }
- *ptrReal++ = signalReal;
- freqInvFlag = !freqInvFlag;
- }
-
- } else
{
if (!(harmIndex&0x1)) {
/* harmIndex 0,2 */
@@ -1933,8 +2002,9 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
*ptrHarmIndex = (harmIndex + 1) & 3;
*ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1);
}
-void adjustTimeSlotHQ(FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */
- FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */
+static void adjustTimeSlotHQ(
+ FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */
+ FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */
HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
ENV_CALC_NRGS* nrgs,
int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
@@ -2137,7 +2207,6 @@ ResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QM
UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
int patchBorders[MAX_NUM_PATCHES + 1];
int kx, k2;
- FIXP_DBL temp;
int lowSubband = freqBandTable[0];
int highSubband = freqBandTable[noFreqBands];
@@ -2169,13 +2238,32 @@ ResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QM
while (hiLimIndex <= tempNoLim) {
+ FIXP_DBL div_m, oct_m, temp;
+ INT div_e = 0, oct_e = 0, temp_e = 0;
+
k2 = workLimiterBandTable[hiLimIndex] + lowSubband;
kx = workLimiterBandTable[loLimIndex] + lowSubband;
- temp = FX_SGL2FX_DBL(FDK_getNumOctavesDiv8(kx,k2)); /* Number of octaves */
- temp = fMult(temp, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[limiterBands]);
+ div_m = fDivNorm(k2, kx, &div_e);
+
+ /* calculate number of octaves */
+ oct_m = fLog2(div_m, div_e, &oct_e);
+
+ /* multiply with limiterbands per octave */
+ /* values 1, 1.2, 2, 3 -> scale factor of 2 */
+ temp = fMultNorm(oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands], &temp_e);
+
+ /* overall scale factor of temp ist addition of scalefactors from log2 calculation,
+ limiter bands scalefactor (2) and limiter bands multiplication */
+ temp_e += oct_e + 2;
+
+ /* div can be a maximum of 64 (k2 = 64 and kx = 1)
+ -> oct can be a maximum of 6
+ -> temp can be a maximum of 18 (as limiterBandsPerOctoave is a maximum factor of 3)
+ -> we need a scale factor of 5 for comparisson
+ */
+ if (temp >> (5 - temp_e) < FL2FXCONST_DBL (0.49f) >> 5) {
- if (temp < FL2FXCONST_DBL (0.49f)>>5) {
if (workLimiterBandTable[hiLimIndex] == workLimiterBandTable[loLimIndex]) {
workLimiterBandTable[hiLimIndex] = highSubband;
nBands--;
diff --git a/libSBRdec/src/env_dec.cpp b/libSBRdec/src/env_dec.cpp
index 24b2d3b..c65c169 100644
--- a/libSBRdec/src/env_dec.cpp
+++ b/libSBRdec/src/env_dec.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -369,7 +369,7 @@ leanSbrConcealment(HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control d
FIXP_SGL step; /* speed of fade */
int i;
- int currentStartPos = h_prev_data->stopPos - hHeaderData->numberTimeSlots;
+ int currentStartPos = FDKmax(0, h_prev_data->stopPos - hHeaderData->numberTimeSlots);
int currentStopPos = hHeaderData->numberTimeSlots;
diff --git a/libSBRdec/src/env_extr.cpp b/libSBRdec/src/env_extr.cpp
index bdb29e5..4d53a13 100644
--- a/libSBRdec/src/env_extr.cpp
+++ b/libSBRdec/src/env_extr.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -327,7 +327,7 @@ sbrGetHeaderData (HANDLE_SBR_HEADER_DATA hHeaderData,
}
/* Look for new settings. IEC 14496-3, 4.6.18.3.1 */
- if(hHeaderData->syncState != SBR_ACTIVE ||
+ if(hHeaderData->syncState < SBR_HEADER ||
lastHeader.startFreq != pBsData->startFreq ||
lastHeader.stopFreq != pBsData->stopFreq ||
lastHeader.freqScale != pBsData->freqScale ||
diff --git a/libSBRdec/src/env_extr.h b/libSBRdec/src/env_extr.h
index ab6b704..0518ea9 100644
--- a/libSBRdec/src/env_extr.h
+++ b/libSBRdec/src/env_extr.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -125,6 +125,7 @@ amm-info@iis.fraunhofer.de
typedef enum
{
HEADER_NOT_PRESENT,
+ HEADER_ERROR,
HEADER_OK,
HEADER_RESET
}
@@ -132,10 +133,10 @@ SBR_HEADER_STATUS;
typedef enum
{
- SBR_NOT_INITIALIZED,
- UPSAMPLING,
- SBR_HEADER,
- SBR_ACTIVE
+ SBR_NOT_INITIALIZED = 0,
+ UPSAMPLING = 1,
+ SBR_HEADER = 2,
+ SBR_ACTIVE = 3
}
SBR_SYNC_STATE;
@@ -179,6 +180,7 @@ 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_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_SYNTAX_DRM 2048 /* Flag indicating that DRM30/DRM+ reverse syntax is being 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. */
diff --git a/libSBRdec/src/sbr_dec.cpp b/libSBRdec/src/sbr_dec.cpp
index 1282338..0864348 100644
--- a/libSBRdec/src/sbr_dec.cpp
+++ b/libSBRdec/src/sbr_dec.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -225,7 +225,14 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand
}
if (resetAnaQmf) {
- int qmfErr = qmfInitAnalysisFilterBank (
+ QMF_FILTER_BANK prvAnaQmf;
+ int qmfErr;
+
+ /* Store current configuration */
+ FDKmemcpy(&prvAnaQmf, &hSbrDec->AnalysiscQMF, sizeof(QMF_FILTER_BANK));
+
+ /* Reset analysis QMF */
+ qmfErr = qmfInitAnalysisFilterBank (
&hSbrDec->AnalysiscQMF,
hSbrDec->anaQmfStates,
hSbrDec->AnalysiscQMF.no_col,
@@ -234,13 +241,22 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand
hSbrDec->AnalysiscQMF.no_channels,
anaQmfFlags | QMF_FLAG_KEEP_STATES
);
+
if (qmfErr != 0) {
- FDK_ASSERT(0);
+ /* Restore old configuration of analysis QMF */
+ FDKmemcpy(&hSbrDec->AnalysiscQMF, &prvAnaQmf, sizeof(QMF_FILTER_BANK));
}
}
if (resetSynQmf) {
- int qmfErr = qmfInitSynthesisFilterBank (
+ QMF_FILTER_BANK prvSynQmf;
+ int qmfErr;
+
+ /* Store current configuration */
+ FDKmemcpy(&prvSynQmf, &hSbrDec->SynthesisQMF, sizeof(QMF_FILTER_BANK));
+
+ /* Reset synthesis QMF */
+ qmfErr = qmfInitSynthesisFilterBank (
&hSbrDec->SynthesisQMF,
hSbrDec->pSynQmfStates,
hSbrDec->SynthesisQMF.no_col,
@@ -251,7 +267,8 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand
);
if (qmfErr != 0) {
- FDK_ASSERT(0);
+ /* Restore old configuration of synthesis QMF */
+ FDKmemcpy(&hSbrDec->SynthesisQMF, &prvSynQmf, sizeof(QMF_FILTER_BANK));
}
}
}
@@ -321,7 +338,8 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */
const int applyProcessing, /*!< Flag for SBR operation */
HANDLE_PS_DEC h_ps_d,
- const UINT flags
+ const UINT flags,
+ const int codecFrameSize
)
{
int i, slot, reserve;
@@ -348,6 +366,33 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
if (flags & SBRDEC_ELD_GRID) {
/* Choose the right low delay filter bank */
changeQmfType( hSbrDec, (flags & SBRDEC_LD_MPS_QMF) ? 1 : 0 );
+
+ /* If the LD-MPS QMF is not available delay the signal by (96-48*ldSbrSamplingRate)
+ * samples according to ISO/IEC 14496-3:2009/FDAM 2:2010(E) chapter 4.5.2.13. */
+ if ( (flags & SBRDEC_LD_MPS_QMF)
+ && (hSbrDec->AnalysiscQMF.flags & QMF_FLAG_CLDFB) )
+ {
+ INT_PCM *pDlyBuf = hSbrDec->coreDelayBuf; /* DLYBUF */
+ int smpl, delay = 96 >> (!(flags & SBRDEC_DOWNSAMPLE) ? 1 : 0);
+ /* Create TMPBUF */
+ C_AALLOC_SCRATCH_START(pcmTemp, INT_PCM, (96));
+ /* Copy delay samples from INBUF to TMPBUF */
+ for (smpl = 0; smpl < delay; smpl += 1) {
+ pcmTemp[smpl] = timeIn[(codecFrameSize-delay+smpl)*strideIn];
+ }
+ /* Move input signal remainder to the very end of INBUF */
+ for (smpl = (codecFrameSize-delay-1)*strideIn; smpl >= 0; smpl -= strideIn) {
+ timeIn[smpl+delay] = timeIn[smpl];
+ }
+ /* Copy delayed samples from last frame from DLYBUF to the very beginning of INBUF */
+ for (smpl = 0; smpl < delay; smpl += 1) {
+ timeIn[smpl*strideIn] = pDlyBuf[smpl];
+ }
+ /* Copy TMPBUF to DLYBUF */
+ FDKmemcpy(pDlyBuf, pcmTemp, delay*sizeof(INT_PCM));
+ /* Destory TMPBUF */
+ C_AALLOC_SCRATCH_END(pcmTemp, INT_PCM, (96));
+ }
}
/*
@@ -761,7 +806,7 @@ createSbrDec (SBR_CHANNEL * hSbrChannel,
{
int qmfErr;
/* Adapted QMF analysis post-twiddles for down-sampled HQ SBR */
- const UINT downSampledFlag = (downsampleFac==2) ? QMF_FLAG_DOWNSAMPLED : 0;
+ const UINT downSampledFlag = (flags & SBRDEC_DOWNSAMPLE) ? QMF_FLAG_DOWNSAMPLED : 0;
qmfErr = qmfInitAnalysisFilterBank (
&hs->AnalysiscQMF,
@@ -836,6 +881,9 @@ createSbrDec (SBR_CHANNEL * hSbrChannel,
}
}
+ /* Clear input delay line */
+ FDKmemclear(hs->coreDelayBuf, (96)*sizeof(INT_PCM));
+
/* assign qmf time slots */
assignTimeSlots( &hSbrChannel->SbrDec, hHeaderData->numberTimeSlots * hHeaderData->timeStep, qmfFlags & QMF_FLAG_LP);
diff --git a/libSBRdec/src/sbr_dec.h b/libSBRdec/src/sbr_dec.h
index 175e7b2..edde637 100644
--- a/libSBRdec/src/sbr_dec.h
+++ b/libSBRdec/src/sbr_dec.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -118,6 +118,9 @@ typedef struct
FIXP_DBL * WorkBuffer1;
FIXP_DBL * WorkBuffer2;
+ /* Delayed time input signal needed to align CLDFD with LD-MPS QMF. */
+ INT_PCM coreDelayBuf[(96)];
+
/* QMF filter states */
FIXP_QAS anaQmfStates[(320)];
FIXP_QSS * pSynQmfStates;
@@ -182,7 +185,8 @@ sbr_dec (HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */
const int applyProcessing, /*!< Flag for SBR operation */
HANDLE_PS_DEC h_ps_d,
- const UINT flags
+ const UINT flags,
+ const int codecFrameSize
);
diff --git a/libSBRdec/src/sbr_ram.h b/libSBRdec/src/sbr_ram.h
index f12631d..7ab5044 100644
--- a/libSBRdec/src/sbr_ram.h
+++ b/libSBRdec/src/sbr_ram.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -135,6 +135,7 @@ struct SBR_DECODER_INSTANCE
USHORT codecFrameSize;
UCHAR synDownsampleFac;
UCHAR numDelayFrames; /* The current number of additional delay frames used for processing. */
+ UCHAR numFlushedFrames; /* The variable counts the number of frames which are flushed consecutively. */
UINT flags;
diff --git a/libSBRdec/src/sbr_rom.cpp b/libSBRdec/src/sbr_rom.cpp
index e84c3cd..c48ce35 100644
--- a/libSBRdec/src/sbr_rom.cpp
+++ b/libSBRdec/src/sbr_rom.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -189,6 +189,15 @@ const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4] =
FL2FXCONST_SGL(3.0f / 4.0f)
};
+/*! Constants for calculating the number of limiter bands */
+const FIXP_DBL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[4] =
+{
+ FL2FXCONST_DBL(1.0f / 4.0f),
+ FL2FXCONST_DBL(1.2f / 4.0f),
+ FL2FXCONST_DBL(2.0f / 4.0f),
+ FL2FXCONST_DBL(3.0f / 4.0f)
+};
+
/*! Ratio of old gains and noise levels for the first 4 timeslots of an envelope */
const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4] = {
FL2FXCONST_SGL(0.66666666666666f),
diff --git a/libSBRdec/src/sbr_rom.h b/libSBRdec/src/sbr_rom.h
index c318870..1f800bc 100644
--- a/libSBRdec/src/sbr_rom.h
+++ b/libSBRdec/src/sbr_rom.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -124,6 +124,7 @@ extern const FIXP_DBL FDK_sbrDecoder_sbr_whFactorsTable[NUM_WHFACTOR_TABLE_ENTRI
extern const FIXP_SGL FDK_sbrDecoder_sbr_limGains_m[4];
extern const UCHAR FDK_sbrDecoder_sbr_limGains_e[4];
extern const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4];
+extern const FIXP_DBL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[4];
extern const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4];
extern const FIXP_SGL FDK_sbrDecoder_sbr_randomPhase[SBR_NF_NO_RANDOM_VAL][2];
extern const FIXP_SGL harmonicPhaseX [2][4];
diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp
index 619e4fd..f9ded54 100644
--- a/libSBRdec/src/sbrdecoder.cpp
+++ b/libSBRdec/src/sbrdecoder.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -128,6 +128,7 @@ amm-info@iis.fraunhofer.de
#include "lpp_tran.h"
#include "transcendent.h"
+#include "FDK_crc.h"
#include "sbrdec_drc.h"
@@ -137,7 +138,7 @@ amm-info@iis.fraunhofer.de
/* Decoder library info */
#define SBRDECODER_LIB_VL0 2
#define SBRDECODER_LIB_VL1 2
-#define SBRDECODER_LIB_VL2 6
+#define SBRDECODER_LIB_VL2 12
#define SBRDECODER_LIB_TITLE "SBR Decoder"
#ifdef __ANDROID__
#define SBRDECODER_LIB_BUILD_DATE ""
@@ -194,6 +195,33 @@ static void copySbrHeader( HANDLE_SBR_HEADER_DATA hDst, const HANDLE_SBR_HEADER_
hDst->freqBandData.freqBandTable[1] = hDst->freqBandData.freqBandTableHi;
}
+static int compareSbrHeader( const HANDLE_SBR_HEADER_DATA hHdr1, const HANDLE_SBR_HEADER_DATA hHdr2 )
+{
+ int result = 0;
+
+ /* compare basic data */
+ result |= (hHdr1->syncState != hHdr2->syncState) ? 1 : 0;
+ result |= (hHdr1->status != hHdr2->status) ? 1 : 0;
+ result |= (hHdr1->frameErrorFlag != hHdr2->frameErrorFlag) ? 1 : 0;
+ result |= (hHdr1->numberTimeSlots != hHdr2->numberTimeSlots) ? 1 : 0;
+ result |= (hHdr1->numberOfAnalysisBands != hHdr2->numberOfAnalysisBands) ? 1 : 0;
+ result |= (hHdr1->timeStep != hHdr2->timeStep) ? 1 : 0;
+ result |= (hHdr1->sbrProcSmplRate != hHdr2->sbrProcSmplRate) ? 1 : 0;
+
+ /* compare bitstream data */
+ result |= FDKmemcmp( &hHdr1->bs_data, &hHdr2->bs_data, sizeof(SBR_HEADER_DATA_BS) );
+ result |= FDKmemcmp( &hHdr1->bs_info, &hHdr2->bs_info, sizeof(SBR_HEADER_DATA_BS_INFO) );
+
+ /* compare frequency band data */
+ result |= FDKmemcmp( &hHdr1->freqBandData, &hHdr2->freqBandData, (8+MAX_NUM_LIMITERS+1)*sizeof(UCHAR) );
+ result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableLo, hHdr2->freqBandData.freqBandTableLo, (MAX_FREQ_COEFFS/2+1)*sizeof(UCHAR) );
+ result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableHi, hHdr2->freqBandData.freqBandTableHi, (MAX_FREQ_COEFFS+1)*sizeof(UCHAR) );
+ result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableNoise, hHdr2->freqBandData.freqBandTableNoise, (MAX_NOISE_COEFFS+1)*sizeof(UCHAR) );
+ result |= FDKmemcmp( hHdr1->freqBandData.v_k_master, hHdr2->freqBandData.v_k_master, (MAX_FREQ_COEFFS+1)*sizeof(UCHAR) );
+
+ return result;
+}
+
/*!
\brief Reset SBR decoder.
@@ -318,7 +346,6 @@ SBR_ERROR sbrDecoder_ResetElement (
case AOT_PS:
case AOT_ER_AAC_SCAL:
case AOT_DRM_AAC:
- case AOT_DRM_SURROUND:
if (CreatePsDec ( &self->hParametricStereoDec, samplesPerFrame )) {
sbrError = SBRDEC_CREATE_ERROR;
goto bail;
@@ -392,6 +419,7 @@ int sbrDecoder_isCoreCodecValid(AUDIO_OBJECT_TYPE coreCodec)
case AOT_PS:
case AOT_ER_AAC_SCAL:
case AOT_ER_AAC_ELD:
+ case AOT_DRM_AAC:
return 1;
default:
return 0;
@@ -464,6 +492,8 @@ SBR_ERROR sbrDecoder_InitElement (
self->flags = 0;
self->flags |= (coreCodec == AOT_ER_AAC_ELD) ? SBRDEC_ELD_GRID : 0;
+ self->flags |= (coreCodec == AOT_ER_AAC_SCAL) ? SBRDEC_SYNTAX_SCAL : 0;
+ self->flags |= (coreCodec == AOT_DRM_AAC) ? SBRDEC_SYNTAX_SCAL|SBRDEC_SYNTAX_DRM : 0;
/* Init SBR elements */
{
@@ -503,7 +533,6 @@ SBR_ERROR sbrDecoder_InitElement (
case AOT_PS:
case AOT_ER_AAC_SCAL:
case AOT_DRM_AAC:
- case AOT_DRM_SURROUND:
elChannels = 2;
break;
default:
@@ -930,24 +959,73 @@ SBR_ERROR sbrDecoder_Parse(
)
{
SBR_DECODER_ELEMENT *hSbrElement;
- HANDLE_SBR_HEADER_DATA hSbrHeader;
+ HANDLE_SBR_HEADER_DATA hSbrHeader = NULL;
HANDLE_SBR_CHANNEL *pSbrChannel;
SBR_FRAME_DATA *hFrameDataLeft;
SBR_FRAME_DATA *hFrameDataRight;
SBR_ERROR errorStatus = SBRDEC_OK;
- SBR_SYNC_STATE initialSyncState;
SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT;
INT startPos;
INT CRCLen = 0;
+ HANDLE_FDK_BITSTREAM hBsOriginal = hBs;
+ FDK_CRCINFO crcInfo; /* shall be used for all other CRCs in the future (TBD) */
+ INT crcReg = 0;
+ USHORT drmSbrCrc = 0;
int stereo;
int fDoDecodeSbrData = 1;
int lastSlot, lastHdrSlot = 0, thisHdrSlot;
+ /* Reverse bits of DRM SBR payload */
+ if ( (self->flags & SBRDEC_SYNTAX_DRM) && *count > 0 )
+ {
+ UCHAR *bsBufferDrm = (UCHAR*)self->workBuffer1;
+ HANDLE_FDK_BITSTREAM hBsBwd = (HANDLE_FDK_BITSTREAM) (bsBufferDrm + (512));
+ int dataBytes, dataBits;
+
+ dataBits = *count;
+
+ if (dataBits > ((512)*8)) {
+ /* do not flip more data than needed */
+ dataBits = (512)*8;
+ }
+
+ dataBytes = (dataBits+7)>>3;
+
+ int j;
+
+ if ((j = (int)FDKgetValidBits(hBs)) != 8) {
+ FDKpushBiDirectional(hBs, (j-8));
+ }
+
+ j = 0;
+ for ( ; dataBytes > 0; dataBytes--)
+ {
+ int i;
+ UCHAR tmpByte;
+ UCHAR buffer = 0x00;
+
+ tmpByte = (UCHAR) FDKreadBits(hBs, 8);
+ for (i = 0; i < 4; i++) {
+ int shift = 2 * i + 1;
+ buffer |= (tmpByte & (0x08>>i)) << shift;
+ buffer |= (tmpByte & (0x10<<i)) >> shift;
+ }
+ bsBufferDrm[j++] = buffer;
+ FDKpushBack(hBs, 16);
+ }
+
+ FDKinitBitStream(hBsBwd, bsBufferDrm, (512), dataBits, BS_READER);
+
+ /* Use reversed data */
+ hBs = hBsBwd;
+ bsPayLen = *count;
+ }
+
/* Remember start position of SBR element */
startPos = FDKgetValidBits(hBs);
@@ -972,7 +1050,6 @@ SBR_ERROR sbrDecoder_Parse(
hFrameDataLeft = &self->pSbrElement[elementIndex]->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot];
hFrameDataRight = &self->pSbrElement[elementIndex]->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];
- initialSyncState = hSbrHeader->syncState;
/* reset PS flag; will be set after PS was found */
self->flags &= ~SBRDEC_PS_DECODED;
@@ -1008,12 +1085,19 @@ SBR_ERROR sbrDecoder_Parse(
*/
if (fDoDecodeSbrData)
{
- if (crcFlag == 1) {
+ if (crcFlag) {
switch (self->coreCodec) {
case AOT_ER_AAC_ELD:
FDKpushFor (hBs, 10);
/* check sbrcrc later: we don't know the payload length now */
break;
+ case AOT_DRM_AAC:
+ drmSbrCrc = (USHORT)FDKreadBits(hBs, 8);
+ /* Setup CRC decoder */
+ FDKcrcInit(&crcInfo, 0x001d, 0xFFFF, 8);
+ /* Start CRC region */
+ crcReg = FDKcrcStartReg(&crcInfo, hBs, 0);
+ break;
default:
CRCLen = bsPayLen - 10; /* change: 0 => i */
if (CRCLen < 0) {
@@ -1058,6 +1142,7 @@ SBR_ERROR sbrDecoder_Parse(
hSbrHeader->syncState = SBR_HEADER;
} else {
hSbrHeader->syncState = SBR_NOT_INITIALIZED;
+ headerStatus = HEADER_ERROR;
}
}
@@ -1107,7 +1192,7 @@ SBR_ERROR sbrDecoder_Parse(
valBits = (INT)FDKgetValidBits(hBs);
}
- if ( crcFlag == 1 ) {
+ if ( crcFlag ) {
switch (self->coreCodec) {
case AOT_ER_AAC_ELD:
{
@@ -1119,6 +1204,14 @@ SBR_ERROR sbrDecoder_Parse(
FDKpushFor(hBs, crcLen);
}
break;
+ case AOT_DRM_AAC:
+ /* End CRC region */
+ FDKcrcEndReg(&crcInfo, hBs, crcReg);
+ /* Check CRC */
+ if ((FDKcrcGetCRC(&crcInfo)^0xFF) != drmSbrCrc) {
+ fDoDecodeSbrData = 0;
+ }
+ break;
default:
break;
}
@@ -1169,8 +1262,25 @@ SBR_ERROR sbrDecoder_Parse(
}
bail:
- if (errorStatus == SBRDEC_OK) {
- if (headerStatus == HEADER_NOT_PRESENT) {
+
+ if ( self->flags & SBRDEC_SYNTAX_DRM )
+ {
+ hBs = hBsOriginal;
+ }
+
+ if ( (errorStatus == SBRDEC_OK)
+ || ( (errorStatus == SBRDEC_PARSE_ERROR)
+ && (headerStatus != HEADER_ERROR) ) )
+ {
+ int useOldHdr = ( (headerStatus == HEADER_NOT_PRESENT)
+ || (headerStatus == HEADER_ERROR) ) ? 1 : 0;
+
+ if (!useOldHdr && (thisHdrSlot != lastHdrSlot)) {
+ useOldHdr |= ( compareSbrHeader( hSbrHeader,
+ &self->sbrHeader[elementIndex][lastHdrSlot] ) == 0 ) ? 1 : 0;
+ }
+
+ if (useOldHdr != 0) {
/* Use the old header for this frame */
hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = lastHdrSlot;
} else {
@@ -1231,12 +1341,21 @@ sbrDecoder_DecodeElement (
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];
+ if ( self->numFlushedFrames > self->numDelayFrames ) {
+ int hdrIdx;
+ /* No valid SBR payload available, hence switch to upsampling (in all headers) */
+ for (hdrIdx = 0; hdrIdx < ((1)+1); hdrIdx += 1) {
+ self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING;
+ }
+ }
+ else {
+ /* 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 */
@@ -1356,7 +1475,8 @@ sbrDecoder_DecodeElement (
&pSbrChannel[0]->prevFrameData,
(hSbrHeader->syncState == SBR_ACTIVE),
h_ps_d,
- self->flags
+ self->flags,
+ codecFrameSize
);
if (stereo) {
@@ -1373,7 +1493,8 @@ sbrDecoder_DecodeElement (
&pSbrChannel[1]->prevFrameData,
(hSbrHeader->syncState == SBR_ACTIVE),
NULL,
- self->flags
+ self->flags,
+ codecFrameSize
);
}
@@ -1389,20 +1510,21 @@ sbrDecoder_DecodeElement (
if ( !(self->flags & SBRDEC_PS_DECODED) ) {
/* A decoder which is able to decode PS has to produce a stereo output even if no PS data is availble. */
/* So copy left channel to right channel. */
+ int copyFrameSize = codecFrameSize * 2 / self->synDownsampleFac;
if (interleaved) {
INT_PCM *ptr;
INT i;
FDK_ASSERT(strideOut == 2);
ptr = timeData;
- for (i = codecFrameSize; i--; )
+ for (i = copyFrameSize>>1; i--; )
{
INT_PCM tmp; /* This temporal variable is required because some compilers can't do *ptr++ = *ptr++ correctly. */
tmp = *ptr++; *ptr++ = tmp;
tmp = *ptr++; *ptr++ = tmp;
}
} else {
- FDKmemcpy( timeData+2*codecFrameSize, timeData, 2*codecFrameSize*sizeof(INT_PCM) );
+ FDKmemcpy( timeData+copyFrameSize, timeData, copyFrameSize*sizeof(INT_PCM) );
}
}
*numOutChannels = 2; /* Output minimum two channels when PS is enabled. */
@@ -1466,14 +1588,23 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self,
self->flags &= ~SBRDEC_PS_DECODED;
}
+ if ( self->flags & SBRDEC_FLUSH ) {
+ /* flushing is signalized, hence increment the flush frame counter */
+ self->numFlushedFrames++;
+ }
+ else {
+ /* no flushing is signalized, hence reset the flush frame counter */
+ self->numFlushedFrames = 0;
+ }
+
/* Loop over SBR elements */
for (sbrElementNum = 0; sbrElementNum<self->numSbrElements; sbrElementNum++)
{
int numElementChan;
if (psPossible && self->pSbrElement[sbrElementNum]->pSbrChannel[1] == NULL) {
- errorStatus = SBRDEC_UNSUPPORTED_CONFIG;
- goto bail;
+ /* Disable PS and try decoding SBR mono. */
+ psPossible = 0;
}
numElementChan = (self->pSbrElement[sbrElementNum]->elementID == ID_CPE) ? 2 : 1;
@@ -1581,6 +1712,7 @@ INT sbrDecoder_GetLibInfo( LIB_INFO *info )
| CAPF_SBR_HQ
| CAPF_SBR_LP
| CAPF_SBR_PS_MPEG
+ | CAPF_SBR_DRM_BS
| CAPF_SBR_CONCEALMENT
| CAPF_SBR_DRC
;
@@ -1609,6 +1741,9 @@ UINT sbrDecoder_GetDelay( const HANDLE_SBRDECODER self )
/* Low delay SBR: */
{
outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 32 : 64; /* QMF synthesis */
+ if (flags & SBRDEC_LD_MPS_QMF) {
+ outputDelay += 32;
+ }
}
}
else if (!IS_USAC(self->coreCodec)) {
diff --git a/libSBRenc/include/sbr_encoder.h b/libSBRenc/include/sbr_encoder.h
index 93dc46d..aec0398 100644
--- a/libSBRenc/include/sbr_encoder.h
+++ b/libSBRenc/include/sbr_encoder.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -135,6 +135,12 @@ enum
SBR_SYNTAX_DRM_CRC = 0x0008
};
+typedef enum
+{
+ FREQ_RES_LOW = 0,
+ FREQ_RES_HIGH
+} FREQ_RES;
+
typedef struct
{
CODEC_TYPE coreCoder; /*!< LC or ELD */
@@ -168,8 +174,9 @@ typedef struct sbrConfiguration
INT dynBwSupported; /*!< Flag: support for dynamic bandwidth in this combination. */
INT parametricCoding; /*!< Flag: usage of parametric coding tool. */
INT downSampleFactor; /*!< Sampling rate relation between the SBR and the core encoder. */
- int freq_res_fixfix[3]; /*!< Frequency resolution of envelopes in frame class FIXFIX
- 0=1 Env; 1=2 Env; 2=4 Env; */
+ FREQ_RES freq_res_fixfix[2];/*!< Frequency resolution of envelopes in frame class FIXFIX, for non-split case and split case */
+ UCHAR fResTransIsLow; /*!< Frequency resolution of envelopes in transient frames: low (0) or variable (1) */
+
/*
core coder dependent tuning parameters
*/
@@ -221,6 +228,8 @@ typedef struct sbrConfiguration
INT sbr_interpol_freq; /*!< Flag: use interpolation in freq. direction. */
INT sbr_smoothing_length; /*!< Flag: choose length 4 or 0 (=on, off). */
UCHAR init_amp_res_FF;
+ FIXP_DBL threshold_AmpRes_FF_m;
+ SCHAR threshold_AmpRes_FF_e;
} sbrConfiguration, *sbrConfigurationPtr ;
typedef struct SBR_CONFIG_DATA
@@ -237,7 +246,7 @@ typedef struct SBR_CONFIG_DATA
INT noQmfBands; /**< Number of QMF frequency bands. */
INT noQmfSlots; /**< Number of QMF slots. */
- UCHAR *freqBandTable[2]; /**< Frequency table for low and hires, only MAX_FREQ_COEFFS/2 +1 coeefs actually needed for lowres. */
+ UCHAR *freqBandTable[2]; /**< Frequency table for low and hires, only MAX_FREQ_COEFFS/2 +1 coeffs actually needed for lowres. */
UCHAR *v_k_master; /**< Master BandTable where freqBandTable is derived from. */
@@ -249,6 +258,8 @@ typedef struct SBR_CONFIG_DATA
INT xposCtrlSwitch; /**< Flag indicates whether to switch xpos ctrl on the fly. */
INT switchTransposers; /**< Flag indicates whether to switch xpos on the fly . */
UCHAR initAmpResFF;
+ FIXP_DBL thresholdAmpResFF_m;
+ SCHAR thresholdAmpResFF_e;
} SBR_CONFIG_DATA, *HANDLE_SBR_CONFIG_DATA;
typedef struct {
diff --git a/libSBRenc/src/bit_sbr.cpp b/libSBRenc/src/bit_sbr.cpp
index 963aeff..9200e01 100644
--- a/libSBRenc/src/bit_sbr.cpp
+++ b/libSBRenc/src/bit_sbr.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -283,9 +283,7 @@ void sbrEncoder_GetHeader(SBR_ENCODER *sbrEncoder,
INT element_index,
int fSendHeaders)
{
- int bits;
-
- bits = encodeSbrHeaderData (&sbrEncoder->sbrElement[element_index]->sbrHeaderData, hBs);
+ encodeSbrHeaderData (&sbrEncoder->sbrElement[element_index]->sbrHeaderData, hBs);
if (fSendHeaders == 0) {
/* Prevent header being embedded into the SBR payload. */
diff --git a/libSBRenc/src/bit_sbr.h b/libSBRenc/src/bit_sbr.h
index 1ce2c1e..de4ac89 100644
--- a/libSBRenc/src/bit_sbr.h
+++ b/libSBRenc/src/bit_sbr.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -141,8 +141,8 @@ struct SBR_ENV_DATA
{
INT sbr_xpos_ctrl;
- INT freq_res_fixfix;
-
+ FREQ_RES freq_res_fixfix[2];
+ UCHAR fResTransIsLow;
INVF_MODE sbr_invf_mode;
INVF_MODE sbr_invf_mode_vec[MAX_NUM_NOISE_VALUES];
@@ -205,6 +205,8 @@ struct SBR_ENV_DATA
INT balance;
AMP_RES init_sbr_amp_res;
AMP_RES currentAmpResFF;
+ FIXP_DBL ton_HF[SBR_GLOBAL_TONALITY_VALUES]; /* tonality is scaled by 2^19/0.524288f (fract part of RELAXATION) */
+ FIXP_DBL global_tonality;
/* extended data */
INT extended_data;
diff --git a/libSBRenc/src/env_est.cpp b/libSBRenc/src/env_est.cpp
index 929f229..4fcda51 100644
--- a/libSBRenc/src/env_est.cpp
+++ b/libSBRenc/src/env_est.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -103,6 +103,114 @@ static const UCHAR panTable[2][10] = { { 0, 2, 4, 6, 8,12,16,20,24},
static const UCHAR maxIndex[2] = {9, 5};
+/******************************************************************************
+ Functionname: FDKsbrEnc_GetTonality
+******************************************************************************/
+/***************************************************************************/
+/*!
+
+ \brief Calculates complete energy per band from the energy values
+ of the QMF subsamples.
+
+ \brief quotaMatrix - calculated in FDKsbrEnc_CalculateTonalityQuotas()
+ \brief noEstPerFrame - number of estimations per frame
+ \brief startIndex - start index for the quota matrix
+ \brief Energies - energy matrix
+ \brief startBand - start band
+ \brief stopBand - number of QMF bands
+ \brief numberCols - number of QMF subsamples
+
+ \return mean tonality of the 5 bands with the highest energy
+ scaled by 2^(RELAXATION_SHIFT+2)*RELAXATION_FRACT
+
+****************************************************************************/
+static FIXP_DBL FDKsbrEnc_GetTonality(
+ const FIXP_DBL *const *quotaMatrix,
+ const INT noEstPerFrame,
+ const INT startIndex,
+ const FIXP_DBL *const *Energies,
+ const UCHAR startBand,
+ const INT stopBand,
+ const INT numberCols
+ )
+{
+ UCHAR b, e, k;
+ INT no_enMaxBand[SBR_MAX_ENERGY_VALUES] = { -1, -1, -1, -1, -1 };
+ FIXP_DBL energyMax[SBR_MAX_ENERGY_VALUES] = { FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f) };
+ FIXP_DBL energyMaxMin = MAXVAL_DBL; /* min. energy in energyMax array */
+ UCHAR posEnergyMaxMin = 0; /* min. energy in energyMax array position */
+ FIXP_DBL tonalityBand[SBR_MAX_ENERGY_VALUES] = { FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f) };
+ FIXP_DBL globalTonality = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL energyBand[QMF_CHANNELS];
+ INT maxNEnergyValues; /* max. number of max. energy values */
+
+ /*** Sum up energies for each band ***/
+ FDK_ASSERT(numberCols==15||numberCols==16);
+ /* numberCols is always 15 or 16 for ELD. In case of 16 bands, the
+ energyBands are initialized with the [15]th column.
+ The rest of the column energies are added in the next step. */
+ if (numberCols==15) {
+ for (b=startBand; b<stopBand; b++) {
+ energyBand[b]=FL2FXCONST_DBL(0.0f);
+ }
+ } else {
+ for (b=startBand; b<stopBand; b++) {
+ energyBand[b]=Energies[15][b]>>4;
+ }
+ }
+
+ for (k=0; k<15; k++) {
+ for (b=startBand; b<stopBand; b++) {
+ energyBand[b] += Energies[k][b]>>4;
+ }
+ }
+
+ /*** Determine 5 highest band-energies ***/
+ maxNEnergyValues = fMin(SBR_MAX_ENERGY_VALUES, stopBand-startBand);
+
+ /* Get min. value in energyMax array */
+ energyMaxMin = energyMax[0] = energyBand[startBand];
+ no_enMaxBand[0] = startBand;
+ posEnergyMaxMin = 0;
+ for (k=1; k<maxNEnergyValues; k++) {
+ energyMax[k] = energyBand[startBand+k];
+ no_enMaxBand[k] = startBand+k;
+ if (energyMaxMin > energyMax[k]) {
+ energyMaxMin = energyMax[k];
+ posEnergyMaxMin = k;
+ }
+ }
+
+ for (b=startBand+maxNEnergyValues; b<stopBand; b++) {
+ if (energyBand[b] > energyMaxMin) {
+ energyMax[posEnergyMaxMin] = energyBand[b];
+ no_enMaxBand[posEnergyMaxMin] = b;
+
+ /* Again, get min. value in energyMax array */
+ energyMaxMin = energyMax[0];
+ posEnergyMaxMin = 0;
+ for (k=1; k<maxNEnergyValues; k++) {
+ if (energyMaxMin > energyMax[k]) {
+ energyMaxMin = energyMax[k];
+ posEnergyMaxMin = k;
+ }
+ }
+ }
+ }
+ /*** End determine 5 highest band-energies ***/
+
+ /* Get tonality values for 5 highest energies */
+ for (e=0; e<maxNEnergyValues; e++) {
+ tonalityBand[e]=FL2FXCONST_DBL(0.0f);
+ for (k=0; k<noEstPerFrame; k++) {
+ tonalityBand[e] += quotaMatrix[startIndex + k][no_enMaxBand[e]] >> 1;
+ }
+ globalTonality += tonalityBand[e] >> 2; /* headroom of 2+1 (max. 5 additions) */
+ }
+
+ return globalTonality;
+}
+
/***************************************************************************/
/*!
@@ -919,10 +1027,42 @@ FDKsbrEnc_extractSbrEnvelope1 (
hEnvChan->qmfScale);
+ if(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
+ FIXP_DBL tonality = FDKsbrEnc_GetTonality (
+ hEnvChan->TonCorr.quotaMatrix,
+ hEnvChan->TonCorr.numberOfEstimatesPerFrame,
+ hEnvChan->TonCorr.startIndexMatrix,
+ sbrExtrEnv->YBuffer + sbrExtrEnv->YBufferWriteOffset,
+ h_con->freqBandTable[HI][0]+1,
+ h_con->noQmfBands,
+ sbrExtrEnv->no_cols
+ );
+
+ hEnvChan->encEnvData.ton_HF[1] = hEnvChan->encEnvData.ton_HF[0];
+ hEnvChan->encEnvData.ton_HF[0] = tonality;
+
+ /* tonality is scaled by 2^19/0.524288f (fract part of RELAXATION) */
+ hEnvChan->encEnvData.global_tonality = (hEnvChan->encEnvData.ton_HF[0]>>1) + (hEnvChan->encEnvData.ton_HF[1]>>1);
+ }
+
+
/*
Transient detection COEFF Transform OK
*/
+ if(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
+ {
+ FDKsbrEnc_fastTransientDetect(
+ &hEnvChan->sbrFastTransientDetector,
+ sbrExtrEnv->YBuffer,
+ sbrExtrEnv->YBufferScale,
+ sbrExtrEnv->YBufferWriteOffset,
+ eData->transient_info
+ );
+
+ }
+ else
+ {
FDKsbrEnc_transientDetect(&hEnvChan->sbrTransientDetector,
sbrExtrEnv->YBuffer,
sbrExtrEnv->YBufferScale,
@@ -931,6 +1071,7 @@ FDKsbrEnc_extractSbrEnvelope1 (
sbrExtrEnv->YBufferSzShift,
sbrExtrEnv->time_step,
hEnvChan->SbrEnvFrame.frameMiddleSlot);
+ }
@@ -951,7 +1092,8 @@ FDKsbrEnc_extractSbrEnvelope1 (
sbrExtrEnv->YBufferSzShift,
h_con->nSfb[1],
sbrExtrEnv->time_step,
- sbrExtrEnv->no_cols);
+ sbrExtrEnv->no_cols,
+ &hEnvChan->encEnvData.global_tonality);
}
@@ -1128,12 +1270,26 @@ FDKsbrEnc_extractSbrEnvelope2 (
&& ( ed->nEnvelopes == 1 ) )
{
- if (hEnvChan->encEnvData.ldGrid)
- hEnvChan->encEnvData.currentAmpResFF = (AMP_RES)h_con->initAmpResFF;
- else
+ if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
+ {
+ /* Note: global_tonaliy_float_value == ((float)hEnvChan->encEnvData.global_tonality/((INT64)(1)<<(31-(19+2)))/0.524288*(2.0/3.0)));
+ threshold_float_value == ((float)h_con->thresholdAmpResFF_m/((INT64)(1)<<(31-(h_con->thresholdAmpResFF_e)))/0.524288*(2.0/3.0))); */
+ /* decision of SBR_AMP_RES */
+ if (fIsLessThan( /* global_tonality > threshold ? */
+ h_con->thresholdAmpResFF_m, h_con->thresholdAmpResFF_e,
+ hEnvChan->encEnvData.global_tonality, RELAXATION_SHIFT+2 )
+ )
+ {
+ hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
+ }
+ else {
+ hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0;
+ }
+ } else {
hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
+ }
- if ( hEnvChan->encEnvData.currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) {
+ if ( hEnvChan->encEnvData.currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) {
FDKsbrEnc_InitSbrHuffmanTables(&hEnvChan->encEnvData,
&hEnvChan->sbrCodeEnvelope,
@@ -1172,7 +1328,12 @@ FDKsbrEnc_extractSbrEnvelope2 (
}
/* Low energy in low band fix */
- if ( hEnvChan->sbrTransientDetector.prevLowBandEnergy < hEnvChan->sbrTransientDetector.prevHighBandEnergy && hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03))
+ if ( hEnvChan->sbrTransientDetector.prevLowBandEnergy < hEnvChan->sbrTransientDetector.prevHighBandEnergy
+ && hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03)
+ /* The fix needs the non-fast transient detector running.
+ It sets prevLowBandEnergy and prevHighBandEnergy. */
+ && !(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
+ )
{
int i;
diff --git a/libSBRenc/src/env_est.h b/libSBRenc/src/env_est.h
index 5e632a4..e17a974 100644
--- a/libSBRenc/src/env_est.h
+++ b/libSBRenc/src/env_est.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -127,6 +127,7 @@ typedef SBR_EXTRACT_ENVELOPE *HANDLE_SBR_EXTRACT_ENVELOPE;
struct ENV_CHANNEL
{
+ FAST_TRAN_DETECTOR sbrFastTransientDetector;
SBR_TRANSIENT_DETECTOR sbrTransientDetector;
SBR_CODE_ENVELOPE sbrCodeEnvelope;
SBR_CODE_ENVELOPE sbrCodeNoiseFloor;
diff --git a/libSBRenc/src/fram_gen.cpp b/libSBRenc/src/fram_gen.cpp
index 86c3c81..9a35111 100644
--- a/libSBRenc/src/fram_gen.cpp
+++ b/libSBRenc/src/fram_gen.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -266,7 +266,7 @@ static void calcCtrlSignal (HANDLE_SBR_GRID hSbrGrid, FRAME_CLASS frameClass,
static void ctrlSignal2FrameInfo (HANDLE_SBR_GRID hSbrGrid,
HANDLE_SBR_FRAME_INFO hFrameInfo,
- INT freq_res_fixfix);
+ FREQ_RES *freq_res_fixfix);
/* table for 8 time slot index */
@@ -341,8 +341,9 @@ static const FREQ_RES freqRes_table_16[16] = {
static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
HANDLE_SBR_GRID hSbrGrid,
int tranPosInternal,
- int numberTimeSlots
- );
+ int numberTimeSlots,
+ UCHAR fResTransIsLow
+ );
/*!
@@ -402,11 +403,10 @@ FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
const int *v_tuningFreq = v_tuning + 3;
hSbrEnvFrame->v_tuningSegm = v_tuningSegm;
- INT freq_res_fixfix = hSbrEnvFrame->freq_res_fixfix;
if (ldGrid) {
/* in case there was a transient at the very end of the previous frame, start with a transient envelope */
- if(v_transient_info_pre[1] && (numberTimeSlots - v_transient_info_pre[0] < minFrameTranDistance)){
+ if ( !tranFlag && v_transient_info_pre[1] && (numberTimeSlots - v_transient_info_pre[0] < minFrameTranDistance) ){
tranFlag = 1;
tranPos = 0;
}
@@ -529,7 +529,8 @@ FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
generateFixFixOnly ( &(hSbrEnvFrame->SbrFrameInfo),
&(hSbrEnvFrame->SbrGrid),
tranPosInternal,
- numberTimeSlots
+ numberTimeSlots,
+ hSbrEnvFrame->fResTransIsLow
);
return &(hSbrEnvFrame->SbrFrameInfo);
@@ -677,7 +678,7 @@ FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
---------------------------------------------------------------------------*/
ctrlSignal2FrameInfo (&hSbrEnvFrame->SbrGrid,
&hSbrEnvFrame->SbrFrameInfo,
- freq_res_fixfix);
+ hSbrEnvFrame->freq_res_fixfix);
return &hSbrEnvFrame->SbrFrameInfo;
}
@@ -692,7 +693,8 @@ FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
HANDLE_SBR_GRID hSbrGrid,
int tranPosInternal,
- int numberTimeSlots
+ int numberTimeSlots,
+ UCHAR fResTransIsLow
)
{
int nEnv, i, k=0, tranIdx;
@@ -727,8 +729,12 @@ static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
/* adjust segment-frequency-resolution according to the segment-length */
for (i=0; i<nEnv; i++){
k = hSbrFrameInfo->borders[i+1] - hSbrFrameInfo->borders[i];
- hSbrFrameInfo->freqRes[i] = freqResTable[k];
- hSbrGrid->v_f[i] = freqResTable[k];
+ if (!fResTransIsLow)
+ hSbrFrameInfo->freqRes[i] = freqResTable[k];
+ else
+ hSbrFrameInfo->freqRes[i] = FREQ_RES_LOW;
+
+ hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i];
}
hSbrFrameInfo->nEnvelopes = nEnv;
@@ -765,15 +771,16 @@ static void generateFixFixOnly ( HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
*******************************************************************************/
void
-FDKsbrEnc_initFrameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
- INT allowSpread,
- INT numEnvStatic,
- INT staticFraming,
- INT timeSlots,
- INT freq_res_fixfix
- ,int ldGrid
- )
-
+FDKsbrEnc_initFrameInfoGenerator (
+ HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
+ INT allowSpread,
+ INT numEnvStatic,
+ INT staticFraming,
+ INT timeSlots,
+ const FREQ_RES* freq_res_fixfix
+ ,UCHAR fResTransIsLow,
+ INT ldGrid
+ )
{ /* FH 00-06-26 */
FDKmemclear(hSbrEnvFrame,sizeof(SBR_ENVELOPE_FRAME ));
@@ -786,7 +793,9 @@ FDKsbrEnc_initFrameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
hSbrEnvFrame->allowSpread = allowSpread;
hSbrEnvFrame->numEnvStatic = numEnvStatic;
hSbrEnvFrame->staticFraming = staticFraming;
- hSbrEnvFrame->freq_res_fixfix = freq_res_fixfix;
+ hSbrEnvFrame->freq_res_fixfix[0] = freq_res_fixfix[0];
+ hSbrEnvFrame->freq_res_fixfix[1] = freq_res_fixfix[1];
+ hSbrEnvFrame->fResTransIsLow = fResTransIsLow;
hSbrEnvFrame->length_v_bord = 0;
hSbrEnvFrame->length_v_bordFollow = 0;
@@ -804,6 +813,7 @@ FDKsbrEnc_initFrameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
hSbrEnvFrame->dmin = 2;
hSbrEnvFrame->dmax = 16;
hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_512LD;
+ hSbrEnvFrame->SbrGrid.bufferFrameStart = 0;
} else
switch(timeSlots){
case NUMBER_TIME_SLOTS_1920:
@@ -1862,19 +1872,28 @@ createDefFrameInfo(HANDLE_SBR_FRAME_INFO hSbrFrameInfo, INT nEnv, INT nTimeSlots
Functionname: ctrlSignal2FrameInfo
*******************************************************************************
- Description: Calculates frame_info struct from control signal.
+ Description: Convert "clear-text" sbr_grid() to "frame info" used by the
+ envelope and noise floor estimators.
+ This is basically (except for "low level" calculations) the
+ bitstream decoder defined in the MPEG-4 standard, sub clause
+ 4.6.18.3.3, Time / Frequency Grid. See inline comments for
+ explanation of the shorten and noise border algorithms.
Arguments: hSbrGrid - source
hSbrFrameInfo - destination
+ freq_res_fixfix - frequency resolution for FIXFIX frames
Return: void; hSbrFrameInfo contains the updated FRAME_INFO struct
*******************************************************************************/
static void
-ctrlSignal2FrameInfo (HANDLE_SBR_GRID hSbrGrid,
- HANDLE_SBR_FRAME_INFO hSbrFrameInfo,
- INT freq_res_fixfix)
+ctrlSignal2FrameInfo (
+ HANDLE_SBR_GRID hSbrGrid, /* input : the grid handle */
+ HANDLE_SBR_FRAME_INFO hSbrFrameInfo, /* output: the frame info handle */
+ FREQ_RES *freq_res_fixfix /* in/out: frequency resolution for FIXFIX frames */
+ )
{
+ INT frameSplit = 0;
INT nEnv = 0, border = 0, i, k, p /*?*/;
INT *v_r = hSbrGrid->bs_rel_bord;
INT *v_f = hSbrGrid->v_f;
@@ -1887,17 +1906,10 @@ ctrlSignal2FrameInfo (HANDLE_SBR_GRID hSbrGrid,
case FIXFIX:
createDefFrameInfo(hSbrFrameInfo, hSbrGrid->bs_num_env, numberTimeSlots);
- /* At this point all frequency resolutions are set to FREQ_RES_HIGH, so
- * only if freq_res_fixfix is set to FREQ_RES_LOW, they all have to be
- * changed.
- * snd */
- if (freq_res_fixfix == FREQ_RES_LOW) {
- for (i = 0; i < hSbrFrameInfo->nEnvelopes; i++) {
- hSbrFrameInfo->freqRes[i] = FREQ_RES_LOW;
- }
+ frameSplit = (hSbrFrameInfo->nEnvelopes > 1);
+ for (i = 0; i < hSbrFrameInfo->nEnvelopes; i++) {
+ hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i] = freq_res_fixfix[frameSplit];
}
- /* ELD: store current frequency resolution */
- hSbrGrid->v_f[0] = hSbrFrameInfo->freqRes[0];
break;
case FIXVAR:
diff --git a/libSBRenc/src/fram_gen.h b/libSBRenc/src/fram_gen.h
index 3769266..00473d4 100644
--- a/libSBRenc/src/fram_gen.h
+++ b/libSBRenc/src/fram_gen.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -89,6 +89,7 @@ amm-info@iis.fraunhofer.de
#define _FRAM_GEN_H
#include "sbr_def.h" /* for MAX_ENVELOPES and MAX_NOISE_ENVELOPES in struct FRAME_INFO and CODEC_TYPE */
+#include "sbr_encoder.h" /* for FREQ_RES */
#define MAX_ENVELOPES_VARVAR MAX_ENVELOPES /*!< worst case number of envelopes in a VARVAR frame */
#define MAX_ENVELOPES_FIXVAR_VARFIX 4 /*!< worst case number of envelopes in VARFIX and FIXVAR frames */
@@ -114,7 +115,7 @@ typedef enum {
#define NUMBER_TIME_SLOTS_1920 15
#define LD_PRETRAN_OFF 3
-#define FRAME_MIDDLE_SLOT_512LD 0
+#define FRAME_MIDDLE_SLOT_512LD 4
#define NUMBER_TIME_SLOTS_512LD 8
#define TRANSIENT_OFFSET_LD 0
@@ -248,9 +249,10 @@ typedef struct
INT frameMiddleSlot; /*!< transient detector offset in SBR timeslots */
/* basic tuning parameters */
- INT staticFraming; /*!< 1: run static framing in time, i.e. exclusive use of bs_frame_class = FIXFIX */
- INT numEnvStatic; /*!< number of envelopes per frame for static framing */
- INT freq_res_fixfix; /*!< envelope frequency resolution to use for bs_frame_class = FIXFIX */
+ INT staticFraming; /*!< 1: run static framing in time, i.e. exclusive use of bs_frame_class = FIXFIX */
+ INT numEnvStatic; /*!< number of envelopes per frame for static framing */
+ FREQ_RES freq_res_fixfix[2]; /*!< envelope frequency resolution to use for bs_frame_class = FIXFIX; single env and split */
+ UCHAR fResTransIsLow; /*!< frequency resolution for transient frames - always low (0) or according to table (1) */
/* expert tuning parameters */
const int *v_tuningSegm; /*!< segment lengths to use around transient */
@@ -286,14 +288,16 @@ typedef SBR_ENVELOPE_FRAME *HANDLE_SBR_ENVELOPE_FRAME;
void
-FDKsbrEnc_initFrameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
- INT allowSpread,
- INT numEnvStatic,
- INT staticFraming,
- INT timeSlots,
- INT freq_res_fixfix
- ,int ldGrid
- );
+FDKsbrEnc_initFrameInfoGenerator (
+ HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
+ INT allowSpread,
+ INT numEnvStatic,
+ INT staticFraming,
+ INT timeSlots,
+ const FREQ_RES* freq_res_fixfix
+ ,UCHAR fResTransIsLow,
+ INT ldGrid
+ );
HANDLE_SBR_FRAME_INFO
FDKsbrEnc_frameInfoGenerator (HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame,
diff --git a/libSBRenc/src/mh_det.cpp b/libSBRenc/src/mh_det.cpp
index 73d1b8b..bc80a15 100644
--- a/libSBRenc/src/mh_det.cpp
+++ b/libSBRenc/src/mh_det.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -663,10 +663,27 @@ static void transientCleanUp(FIXP_DBL **quotaBuffer,
}
-/**************************************************************************/
+/*****************************************************************************/
/*!
- \brief Do detection for one tonality estimate.
+ \brief Detection for one tonality estimate.
+
+ This is the actual missing harmonics detection, using information from the
+ previous detection.
+
+ If a missing harmonic was detected (in a previous frame) due to too high
+ tonality differences, but there was not enough tonality difference in the
+ current frame, the detection algorithm still continues to trace the strongest
+ tone in the scalefactor band (assuming that this is the tone that is going to
+ be replaced in the decoder). This is done to avoid abrupt endings of sines
+ fading out (e.g. in the glockenspiel).
+
+ The function also tries to estimate where one sine is going to be replaced
+ with multiple sines (due to the patching). This is done by comparing the
+ tonality flatness measure of the original and the SBR signal.
+ The function also tries to estimate (for the scalefactor bands only
+ containing one qmf subband) when a strong tone in the original will be
+ replaced by a strong tone in the adjacent QMF subband.
\return none.
@@ -694,10 +711,10 @@ static void detection(FIXP_DBL *quotaBuffer,
for(i=0;i<nSfb;i++){
thresTemp = (guideVectors.guideVectorDiff[i] != FL2FXCONST_DBL(0.0f))
- ? fixMax(fMult(mhThresh.decayGuideDiff,guideVectors.guideVectorDiff[i]), mhThresh.thresHoldDiffGuide)
+ ? fMax(fMult(mhThresh.decayGuideDiff,guideVectors.guideVectorDiff[i]), mhThresh.thresHoldDiffGuide)
: mhThresh.thresHoldDiff;
- thresTemp = fixMin(thresTemp, mhThresh.thresHoldDiff);
+ thresTemp = fMin(thresTemp, mhThresh.thresHoldDiff);
if(pDiffVecScfb[i] > thresTemp){
pHarmVec[i] = 1;
@@ -813,8 +830,11 @@ static void detectionWithPrediction(FIXP_DBL **quotaBuffer,
if(newDetectionAllowed){
+ /* Since we don't want to use the transient region for detection (since the tonality values
+ tend to be a bit unreliable for this region) the guide-values are copied to the current
+ starting point. */
if(totNoEst > 1){
- start = detectionStart;
+ start = detectionStart+1;
if (start != 0) {
FDKmemcpy(guideVectors[start].guideVectorDiff,guideVectors[0].guideVectorDiff,nSfb*sizeof(FIXP_DBL));
diff --git a/libSBRenc/src/nf_est.cpp b/libSBRenc/src/nf_est.cpp
index 7a3c022..a4c5574 100644
--- a/libSBRenc/src/nf_est.cpp
+++ b/libSBRenc/src/nf_est.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -268,8 +268,9 @@ qmfBasedNoiseFloorDetection(FIXP_DBL *noiseLevel, /*!< Pointer to v
/*
* Add a noise floor offset to compensate for bias in the detector
*****************************************************************/
- if(!missingHarmonicFlag)
- *noiseLevel = fMult(*noiseLevel, noiseFloorOffset)<<(NOISE_FLOOR_OFFSET_SCALING);
+ if(!missingHarmonicFlag) {
+ *noiseLevel = fixMin(fMult(*noiseLevel, noiseFloorOffset), (FIXP_DBL)MAXVAL_DBL>>NOISE_FLOOR_OFFSET_SCALING) << NOISE_FLOOR_OFFSET_SCALING;
+ }
/*
* check to see that we don't exceed the maximum allowed level
@@ -297,7 +298,7 @@ FDKsbrEnc_sbrNoiseFloorEstimateQmf(HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoiseFlo
SCHAR *indexVector, /*!< Index vector to obtain the patched data. */
INT missingHarmonicsFlag, /*!< Flag indicating if a strong tonal component will be missing. */
INT startIndex, /*!< Start index. */
- int numberOfEstimatesPerFrame, /*!< The number of tonality estimates per frame. */
+ UINT numberOfEstimatesPerFrame, /*!< The number of tonality estimates per frame. */
int transientFrame, /*!< A flag indicating if a transient is present. */
INVF_MODE* pInvFiltLevels, /*!< Pointer to the vector holding the inverse filtering levels. */
UINT sbrSyntaxFlags
diff --git a/libSBRenc/src/nf_est.h b/libSBRenc/src/nf_est.h
index d407274..f26f74f 100644
--- a/libSBRenc/src/nf_est.h
+++ b/libSBRenc/src/nf_est.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -119,7 +119,7 @@ FDKsbrEnc_sbrNoiseFloorEstimateQmf(HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoiseFlo
SCHAR* indexVector, /*!< Index vector to obtain the patched data. */
INT missingHarmonicsFlag, /*!< Flag indicating if a strong tonal component will be missing. */
INT startIndex, /*!< Start index. */
- int numberOfEstimatesPerFrame, /*!< The number of tonality estimates per frame. */
+ UINT numberOfEstimatesPerFrame, /*!< The number of tonality estimates per frame. */
INT transientFrame, /*!< A flag indicating if a transient is present. */
INVF_MODE* pInvFiltLevels, /*!< Pointer to the vector holding the inverse filtering levels. */
UINT sbrSyntaxFlags
diff --git a/libSBRenc/src/ps_bitenc.cpp b/libSBRenc/src/ps_bitenc.cpp
index 8a42a20..420ea15 100644
--- a/libSBRenc/src/ps_bitenc.cpp
+++ b/libSBRenc/src/ps_bitenc.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -261,21 +261,23 @@ static const UINT opdDeltaTime_Code[] =
0x00000001, 0x00000002, 0x00000001, 0x00000007, 0x00000006, 0000000000, 0x00000002, 0x00000003
};
-static const INT psBands[] =
+static INT getNoBands(const INT mode)
{
- PS_BANDS_COARSE,
- PS_BANDS_MID
-};
-
-static INT getNoBands(UINT mode)
-{
- if(mode>=6)
- return 0;
+ INT noBands = 0;
- if(mode>=3)
- mode = mode-3;
+ switch (mode) {
+ case 0: case 3: /* coarse */
+ noBands = PS_BANDS_COARSE;
+ break;
+ case 1: case 4: /* mid */
+ noBands = PS_BANDS_MID;
+ break;
+ case 2: case 5: /* fine not supported */
+ default: /* coarse as default */
+ noBands = PS_BANDS_COARSE;
+ }
- return psBands[mode];
+ return noBands;
}
static INT getIIDRes(INT iidMode)
@@ -524,7 +526,7 @@ static INT encodeIpdOpd(HANDLE_PS_OUT psOut,
bitCnt += FDKsbrEnc_EncodeIpd( hBitBuf,
psOut->ipd[env],
ipdLast,
- getNoBands((UINT)psOut->iidMode),
+ getNoBands(psOut->iidMode),
psOut->deltaIPD[env],
&error);
@@ -532,7 +534,7 @@ static INT encodeIpdOpd(HANDLE_PS_OUT psOut,
bitCnt += FDKsbrEnc_EncodeOpd( hBitBuf,
psOut->opd[env],
opdLast,
- getNoBands((UINT)psOut->iidMode),
+ getNoBands(psOut->iidMode),
psOut->deltaOPD[env],
&error );
}
@@ -661,7 +663,7 @@ INT FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT psOut,
bitCnt += FDKsbrEnc_EncodeIid( hBitBuf,
psOut->iid[env],
iidLast,
- getNoBands((UINT)psOut->iidMode),
+ getNoBands(psOut->iidMode),
(PS_IID_RESOLUTION)getIIDRes(psOut->iidMode),
psOut->deltaIID[env],
&error );
@@ -677,7 +679,7 @@ INT FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT psOut,
bitCnt += FDKsbrEnc_EncodeIcc( hBitBuf,
psOut->icc[env],
iccLast,
- getNoBands((UINT)psOut->iccMode),
+ getNoBands(psOut->iccMode),
psOut->deltaICC[env],
&error);
diff --git a/libSBRenc/src/ps_encode.cpp b/libSBRenc/src/ps_encode.cpp
index 2ae2788..fec39e8 100644
--- a/libSBRenc/src/ps_encode.cpp
+++ b/libSBRenc/src/ps_encode.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -149,21 +149,21 @@ typedef enum {
static const FIXP_DBL iidQuant_fx[15] = {
- 0xce000000, 0xdc000000, 0xe4000000, 0xec000000, 0xf2000000, 0xf8000000, 0xfc000000, 0x00000000,
- 0x04000000, 0x08000000, 0x0e000000, 0x14000000, 0x1c000000, 0x24000000, 0x32000000
+ (FIXP_DBL)0xce000000, (FIXP_DBL)0xdc000000, (FIXP_DBL)0xe4000000, (FIXP_DBL)0xec000000, (FIXP_DBL)0xf2000000, (FIXP_DBL)0xf8000000, (FIXP_DBL)0xfc000000, (FIXP_DBL)0x00000000,
+ (FIXP_DBL)0x04000000, (FIXP_DBL)0x08000000, (FIXP_DBL)0x0e000000, (FIXP_DBL)0x14000000, (FIXP_DBL)0x1c000000, (FIXP_DBL)0x24000000, (FIXP_DBL)0x32000000
};
static const FIXP_DBL iidQuantFine_fx[31] = {
- 0x9c000001, 0xa6000001, 0xb0000001, 0xba000001, 0xc4000000, 0xce000000, 0xd4000000, 0xda000000,
- 0xe0000000, 0xe6000000, 0xec000000, 0xf0000000, 0xf4000000, 0xf8000000, 0xfc000000, 0x00000000,
- 0x04000000, 0x08000000, 0x0c000000, 0x10000000, 0x14000000, 0x1a000000, 0x20000000, 0x26000000,
- 0x2c000000, 0x32000000, 0x3c000000, 0x45ffffff, 0x4fffffff, 0x59ffffff, 0x63ffffff
+ (FIXP_DBL)0x9c000001, (FIXP_DBL)0xa6000001, (FIXP_DBL)0xb0000001, (FIXP_DBL)0xba000001, (FIXP_DBL)0xc4000000, (FIXP_DBL)0xce000000, (FIXP_DBL)0xd4000000, (FIXP_DBL)0xda000000,
+ (FIXP_DBL)0xe0000000, (FIXP_DBL)0xe6000000, (FIXP_DBL)0xec000000, (FIXP_DBL)0xf0000000, (FIXP_DBL)0xf4000000, (FIXP_DBL)0xf8000000, (FIXP_DBL)0xfc000000, (FIXP_DBL)0x00000000,
+ (FIXP_DBL)0x04000000, (FIXP_DBL)0x08000000, (FIXP_DBL)0x0c000000, (FIXP_DBL)0x10000000, (FIXP_DBL)0x14000000, (FIXP_DBL)0x1a000000, (FIXP_DBL)0x20000000, (FIXP_DBL)0x26000000,
+ (FIXP_DBL)0x2c000000, (FIXP_DBL)0x32000000, (FIXP_DBL)0x3c000000, (FIXP_DBL)0x45ffffff, (FIXP_DBL)0x4fffffff, (FIXP_DBL)0x59ffffff, (FIXP_DBL)0x63ffffff
};
static const FIXP_DBL iccQuant[8] = {
- 0x7fffffff, 0x77ef9d7f, 0x6babc97f, 0x4ceaf27f, 0x2f0ed3c0, 0x00000000, 0xb49ba601, 0x80000000
+ (FIXP_DBL)0x7fffffff, (FIXP_DBL)0x77ef9d7f, (FIXP_DBL)0x6babc97f, (FIXP_DBL)0x4ceaf27f, (FIXP_DBL)0x2f0ed3c0, (FIXP_DBL)0x00000000, (FIXP_DBL)0xb49ba601, (FIXP_DBL)0x80000000
};
static FDK_PSENC_ERROR InitPSData(
diff --git a/libSBRenc/src/sbr_def.h b/libSBRenc/src/sbr_def.h
index 8b7cfc6..85ac587 100644
--- a/libSBRenc/src/sbr_def.h
+++ b/libSBRenc/src/sbr_def.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -122,6 +122,8 @@ amm-info@iis.fraunhofer.de
/************ Definitions ***************/
#define SBR_COMP_MODE_DELTA 0
#define SBR_COMP_MODE_CTS 1
+#define SBR_MAX_ENERGY_VALUES 5
+#define SBR_GLOBAL_TONALITY_VALUES 2
#define MAX_NUM_CHANNELS 2
@@ -232,6 +234,8 @@ amm-info@iis.fraunhofer.de
#define FREQ 0
#define TIME 1
+/* qmf data scaling */
+#define QMF_SCALE_OFFSET 7
/* huffman tables */
#define CODE_BOOK_SCF_LAV00 60
@@ -268,12 +272,4 @@ typedef enum
}
INVF_MODE;
-typedef enum
-{
- FREQ_RES_LOW = 0,
- FREQ_RES_HIGH
-}
-FREQ_RES;
-
-
#endif
diff --git a/libSBRenc/src/sbr_encoder.cpp b/libSBRenc/src/sbr_encoder.cpp
index abe9793..86a3f91 100644
--- a/libSBRenc/src/sbr_encoder.cpp
+++ b/libSBRenc/src/sbr_encoder.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -103,7 +103,7 @@ amm-info@iis.fraunhofer.de
#define SBRENCODER_LIB_VL0 3
#define SBRENCODER_LIB_VL1 3
-#define SBRENCODER_LIB_VL2 4
+#define SBRENCODER_LIB_VL2 12
@@ -170,7 +170,6 @@ getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */
{
int i, bitRateClosestLowerIndex=-1, bitRateClosestUpperIndex=-1, found = 0;
UINT bitRateClosestUpper = 0, bitRateClosestLower=DISTANCE_CEIL_VALUE;
- int isforThisCodec=0;
#define isForThisCore(i) \
( ( sbrTuningTable[i].coreCoder == CODEC_AACLD && core == AOT_ER_AAC_ELD ) || \
@@ -413,6 +412,23 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
config->codecSettings.transFac = transFac;
config->codecSettings.standardBitrate = standardBitrate;
+ if (bitRate < 28000) {
+ config->threshold_AmpRes_FF_m = (FIXP_DBL)MAXVAL_DBL;
+ config->threshold_AmpRes_FF_e = 7;
+ }
+ else if (bitRate >= 28000 && bitRate <= 48000) {
+ /* The float threshold is 75
+ 0.524288f is fractional part of RELAXATION, the quotaMatrix and therefore tonality are scaled by this
+ 2/3 is because the original implementation divides the tonality values by 3, here it's divided by 2
+ 128 compensates the necessary shiftfactor of 7 */
+ config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(75.0f*0.524288f/(2.0f/3.0f)/128.0f);
+ config->threshold_AmpRes_FF_e = 7;
+ }
+ else if (bitRate > 48000) {
+ config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(0);
+ config->threshold_AmpRes_FF_e = 0;
+ }
+
if (bitRate==0) {
/* map vbr quality to bitrate */
if (vbrMode < 30)
@@ -468,6 +484,57 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif
config->stereoMode = sbrTuningTable[idx].stereoMode ;
config->freqScale = sbrTuningTable[idx].freqScale ;
+ if (numChannels == 1) {
+ /* stereo case */
+ switch (core) {
+ case AOT_AAC_LC:
+ if (bitRate <= (useSpeechConfig?24000U:20000U)) {
+ config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
+ config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
+ }
+ break;
+ case AOT_ER_AAC_ELD:
+ if (bitRate < 36000)
+ config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
+ if (bitRate < 26000) {
+ config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
+ config->fResTransIsLow = 1; /* for transient frames, set low frequency resolution */
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else {
+ /* stereo case */
+ switch (core) {
+ case AOT_AAC_LC:
+ if (bitRate <= 28000) {
+ config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
+ config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
+ }
+ break;
+ case AOT_ER_AAC_ELD:
+ if (bitRate < 72000) {
+ config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */
+ }
+ if (bitRate < 52000) {
+ config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */
+ config->fResTransIsLow = 1; /* for transient frames, set low frequency resolution */
+ }
+ break;
+ default:
+ break;
+ }
+ if (bitRate <= 28000) {
+ /*
+ additionally restrict frequency resolution in FIXFIX frames
+ to further reduce SBR payload size */
+ config->freq_res_fixfix[0] = FREQ_RES_LOW;
+ config->freq_res_fixfix[1] = FREQ_RES_LOW;
+ }
+ }
+
/* adjust usage of parametric coding dependent on bitrate and speech config flag */
if (useSpeechConfig)
config->parametricCoding = 0;
@@ -516,6 +583,7 @@ static UINT
FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
INT downSampleFactor,
UINT codecGranuleLen
+ ,const INT isLowDelay
)
{
if ( (downSampleFactor < 1 || downSampleFactor > 2) ||
@@ -526,7 +594,11 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
config->useWaveCoding = 0;
config->crcSbr = 0;
config->dynBwSupported = 1;
- config->tran_thr = 13000;
+ if (isLowDelay)
+ config->tran_thr = 6000;
+ else
+ config->tran_thr = 13000;
+
config->parametricCoding = 1;
config->sbrFrameSize = codecGranuleLen * downSampleFactor;
@@ -559,7 +631,9 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config,
config->noiseFloorOffset = 0;
config->startFreq = 5; /* 5.9 respectively 6.0 kHz at fs = 44.1/48 kHz */
config->stopFreq = 9; /* 16.2 respectively 16.8 kHz at fs = 44.1/48 kHz */
-
+ config->freq_res_fixfix[0] = FREQ_RES_HIGH; /* non-split case */
+ config->freq_res_fixfix[1] = FREQ_RES_HIGH; /* split case */
+ config->fResTransIsLow = 0; /* for transient frames, set variable frequency resolution according to freqResTable */
/* header_extra_1 */
config->freqScale = SBR_FREQ_SCALE_DEFAULT;
@@ -854,7 +928,7 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder,
int clearOutput /*!< Do not consider any input signal */
)
{
- HANDLE_SBR_ELEMENT hSbrElement = hEnvEncoder->sbrElement[iElement];
+ HANDLE_SBR_ELEMENT hSbrElement = NULL;
FDK_CRCINFO crcInfo;
INT crcReg;
INT ch;
@@ -1207,7 +1281,10 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
FDK_ASSERT(params->e >= 0);
- hEnv->encEnvData.freq_res_fixfix = 1;
+ hEnv->encEnvData.freq_res_fixfix[0] = params->freq_res_fixfix[0];
+ hEnv->encEnvData.freq_res_fixfix[1] = params->freq_res_fixfix[1];
+ hEnv->encEnvData.fResTransIsLow = params->fResTransIsLow;
+
hEnv->fLevelProtect = 0;
hEnv->encEnvData.ldGrid = (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? 1 : 0;
@@ -1349,11 +1426,29 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData,
e,
params->stat,
timeSlots,
- hEnv->encEnvData.freq_res_fixfix
- ,hEnv->encEnvData.ldGrid
+ hEnv->encEnvData.freq_res_fixfix,
+ hEnv->encEnvData.fResTransIsLow,
+ hEnv->encEnvData.ldGrid
);
+ if(sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
+ {
+ INT bandwidth_qmf_slot = (sbrConfigData->sampleFreq>>1) / (sbrConfigData->noQmfBands);
+ if(FDKsbrEnc_InitSbrFastTransientDetector(
+ &hEnv->sbrFastTransientDetector,
+ sbrConfigData->noQmfSlots,
+ bandwidth_qmf_slot,
+ sbrConfigData->noQmfBands,
+ sbrConfigData->freqBandTable[0][0]
+ ))
+ return(1);
+ }
+
+ /* The transient detector has to be initialized also if the fast transient
+ detector was active, because the values from the transient detector
+ structure are used. */
if(FDKsbrEnc_InitSbrTransientDetector (&hEnv->sbrTransientDetector,
+ sbrConfigData->sbrSyntaxFlags,
sbrConfigData->frameSize,
sbrConfigData->sampleFreq,
params,
@@ -1553,12 +1648,6 @@ INT FDKsbrEnc_EnvInit (
hSbrElement->sbrConfigData.sbrSyntaxFlags = 0;
switch (aot) {
- case AOT_DRM_MPEG_PS:
- case AOT_DRM_SBR:
- hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_SCALABLE;
- hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_DRM_CRC;
- hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC;
- break;
case AOT_ER_AAC_ELD:
hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_LOW_DELAY;
break;
@@ -1665,6 +1754,8 @@ INT FDKsbrEnc_EnvInit (
/* other switches */
hSbrElement->sbrConfigData.useWaveCoding = params->useWaveCoding;
hSbrElement->sbrConfigData.useParametricCoding = params->parametricCoding;
+ hSbrElement->sbrConfigData.thresholdAmpResFF_m = params->threshold_AmpRes_FF_m;
+ hSbrElement->sbrConfigData.thresholdAmpResFF_e = params->threshold_AmpRes_FF_e;
/* init freq band table */
if(updateFreqBandTable(&hSbrElement->sbrConfigData,
@@ -1848,7 +1939,7 @@ INT sbrEncoder_Init(
- if ( (aot==AOT_PS) || (aot==AOT_MP2_PS) || (aot==AOT_DABPLUS_PS) || (aot==AOT_DRM_MPEG_PS) ) {
+ if ( (aot==AOT_PS) ) {
usePs = 1;
}
if ( aot==AOT_ER_AAC_ELD ) {
@@ -2006,7 +2097,8 @@ INT sbrEncoder_Init(
*/
if ( ! FDKsbrEnc_InitializeSbrDefaults ( &sbrConfig[el],
*downSampleFactor,
- coreFrameLength
+ coreFrameLength,
+ IS_LOWDELAY(aot)
) )
{
error = 1;
diff --git a/libSBRenc/src/sbr_rom.cpp b/libSBRenc/src/sbr_rom.cpp
index a2b6527..7a51668 100644
--- a/libSBRenc/src/sbr_rom.cpp
+++ b/libSBRenc/src/sbr_rom.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -684,6 +684,9 @@ const sbrTuningTable_t sbrTuningTable[] =
/** AAC LOW DELAY SECTION **/
+ /* 24 kHz dual rate - 12kHz singlerate is not allowed (deactivated in FDKsbrEnc_IsSbrSettingAvail()) */
+ { CODEC_AACLD, 8000, 32000, 12000, 1, 1, 1, 0, 0, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 8 kbit/s */
+
/*** mono ***/
/* 16/32 kHz dual rate not yet tuned ->alb copied from non LD tables*/
{ CODEC_AACLD, 16000, 18000, 16000, 1, 4, 5, 9, 7, 1, 0, 6, SBR_MONO, 3 }, /* nominal: 16 kbit/s wrr: tuned */
@@ -702,10 +705,10 @@ const sbrTuningTable_t sbrTuningTable[] =
{ CODEC_AACLD, 52000, 64001, 22050, 1, 13,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 56 kbit/s */
/* 24/48 kHz dual rate */
- { CODEC_AACLD, 20000, 22000, 24000, 1, 4, 1, 8, 4, 2, 3, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */
+ { CODEC_AACLD, 20000, 22000, 24000, 1, 3, 4, 8, 8, 2, 0, 6, SBR_MONO, 2 }, /* nominal: 20 kbit/s */
{ CODEC_AACLD, 22000, 28000, 24000, 1, 3, 8, 8, 7, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 24 kbit/s */
{ CODEC_AACLD, 28000, 36000, 24000, 1, 4, 8, 8, 7, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 32 kbit/s */
- { CODEC_AACLD, 36000, 56000, 24000, 1, 8, 9, 9, 9, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */
+ { CODEC_AACLD, 36000, 56000, 24000, 1, 8, 9, 9, 8, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 40 kbit/s */
{ CODEC_AACLD, 56000, 64001, 24000, 1, 13,11,11,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 kbit/s */
/* 32/64 kHz dual rate */ /* placebo settings */ /*jgr: new, copy from CODEC_AAC */
@@ -722,7 +725,7 @@ const sbrTuningTable_t sbrTuningTable[] =
{ CODEC_AACLD, 100000,160001, 44100, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */
/* 48/96 kHz dual rate */ /* 32 and 40kbps line tuned for dual-rate SBR */
- { CODEC_AACLD, 36000, 60000, 48000, 1, 8, 7, 6, 9, 2, 0, 3, SBR_MONO, 2 }, /* nominal: 40 */
+ { CODEC_AACLD, 36000, 60000, 48000, 1, 4, 7, 4, 4, 2, 0, 3, SBR_MONO, 3 }, /* nominal: 40 */
{ CODEC_AACLD, 60000, 72000, 48000, 1, 9, 9,10,10, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 64 */
{ CODEC_AACLD, 72000,100000, 48000, 1, 11,11,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 80 */
{ CODEC_AACLD, 100000,160001, 48000, 1, 13,13,11,11, 2, 0, 3, SBR_MONO, 1 }, /* nominal: 128 */
diff --git a/libSBRenc/src/ton_corr.cpp b/libSBRenc/src/ton_corr.cpp
index 224da11..af5afba 100644
--- a/libSBRenc/src/ton_corr.cpp
+++ b/libSBRenc/src/ton_corr.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -682,7 +682,7 @@ FDKsbrEnc_InitTonCorrParamExtr (INT frameSize, /*!< Current
/*
Reset the patching and allocate memory for the quota matrix.
- Assing parameters for the LPC analysis.
+ Assuming parameters for the LPC analysis.
*/
if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
switch (timeSlots) {
@@ -690,7 +690,7 @@ FDKsbrEnc_InitTonCorrParamExtr (INT frameSize, /*!< Current
hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
hTonCorr->lpcLength[1] = 7 - LPC_ORDER;
hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
- hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 7;
+ hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 7 */
hTonCorr->frameStartIndexInvfEst = 0;
hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
break;
@@ -698,7 +698,7 @@ FDKsbrEnc_InitTonCorrParamExtr (INT frameSize, /*!< Current
hTonCorr->lpcLength[0] = 8 - LPC_ORDER;
hTonCorr->lpcLength[1] = 8 - LPC_ORDER;
hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD;
- hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 8;
+ hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 8 */
hTonCorr->frameStartIndexInvfEst = 0;
hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
break;
diff --git a/libSBRenc/src/ton_corr.h b/libSBRenc/src/ton_corr.h
index 8c8425c..504ab03 100644
--- a/libSBRenc/src/ton_corr.h
+++ b/libSBRenc/src/ton_corr.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -118,7 +118,7 @@ typedef struct
INT bufferLength; /*!< Length of the r and i buffers. */
INT stepSize; /*!< Stride for the lpc estimate. */
INT numberOfEstimates; /*!< The total number of estiamtes, available in the quotaMatrix.*/
- INT numberOfEstimatesPerFrame; /*!< The number of estimates per frame available in the quotaMatrix.*/
+ UINT numberOfEstimatesPerFrame; /*!< The number of estimates per frame available in the quotaMatrix.*/
INT lpcLength[2]; /*!< Segment length used for second order LPC analysis.*/
INT nextSample; /*!< Where to start the LPC analysis of the current frame.*/
INT move; /*!< How many estimates to move in the quotaMatrix, when buffering. */
diff --git a/libSBRenc/src/tran_det.cpp b/libSBRenc/src/tran_det.cpp
index 1e0a59f..33ea60e 100644
--- a/libSBRenc/src/tran_det.cpp
+++ b/libSBRenc/src/tran_det.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -89,7 +89,7 @@ amm-info@iis.fraunhofer.de
#include "genericStds.h"
-#define NORM_QMF_ENERGY 5.684341886080801486968994140625e-14 /* 2^-44 */
+#define NORM_QMF_ENERGY 9.31322574615479E-10 /* 2^-30 */
/* static FIXP_DBL ABS_THRES = fixMax( FL2FXCONST_DBL(1.28e5 * NORM_QMF_ENERGY), (FIXP_DBL)1) Minimum threshold for detecting changes */
#define ABS_THRES ((FIXP_DBL)16)
@@ -106,22 +106,30 @@ amm-info@iis.fraunhofer.de
\return calculated value
*******************************************************************************/
+#define NRG_SHIFT 3 /* for energy summation */
+
static FIXP_DBL spectralChange(FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS],
INT *scaleEnergies,
FIXP_DBL EnergyTotal,
INT nSfb,
INT start,
INT border,
- INT stop)
+ INT YBufferWriteOffset,
+ INT stop,
+ INT *result_e)
{
INT i,j;
INT len1,len2;
- FIXP_DBL delta,tmp0,tmp1,tmp2;
- FIXP_DBL accu1,accu2,delta_sum,result;
+ SCHAR energies_e_diff[NUMBER_TIME_SLOTS_2304], energies_e, energyTotal_e=19, energies_e_add;
+ SCHAR prevEnergies_e_diff, newEnergies_e_diff;
+ FIXP_DBL tmp0,tmp1;
+ FIXP_DBL accu1,accu2,accu1_init,accu2_init;
+ FIXP_DBL delta, delta_sum;
+ INT accu_e, tmp_e;
- FDK_ASSERT(scaleEnergies[0] >= 0);
+ delta_sum = FL2FXCONST_DBL(0.0f);
+ *result_e = 0;
- /* equal for aac (would be not equal for mp3) */
len1 = border-start;
len2 = stop-border;
@@ -130,43 +138,91 @@ static FIXP_DBL spectralChange(FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FRE
pos_weight = FL2FXCONST_DBL(0.5f) - (len1*GetInvInt(len1+len2));
pos_weight = /*FL2FXCONST_DBL(1.0)*/ (FIXP_DBL)MAXVAL_DBL - (fMult(pos_weight, pos_weight)<<2);
- delta_sum = FL2FXCONST_DBL(0.0f);
+ /*** Calc scaling for energies ***/
+ FDK_ASSERT(scaleEnergies[0] >= 0);
+ FDK_ASSERT(scaleEnergies[1] >= 0);
+
+ energies_e = 19 - FDKmin(scaleEnergies[0], scaleEnergies[1]);
+
+ /* limit shift for energy accumulation, energies_e can be -10 min. */
+ if (energies_e < -10) {
+ energies_e_add = -10 - energies_e;
+ energies_e = -10;
+ } else if (energies_e > 17) {
+ energies_e_add = energies_e - 17;
+ energies_e = 17;
+ } else {
+ energies_e_add = 0;
+ }
+
+ /* compensate scaling differences between scaleEnergies[0] and scaleEnergies[1] */
+ prevEnergies_e_diff = scaleEnergies[0] - FDKmin(scaleEnergies[0], scaleEnergies[1]) + energies_e_add + NRG_SHIFT;
+ newEnergies_e_diff = scaleEnergies[1] - FDKmin(scaleEnergies[0], scaleEnergies[1]) + energies_e_add + NRG_SHIFT;
+
+ prevEnergies_e_diff = fMin(prevEnergies_e_diff, DFRACT_BITS-1);
+ newEnergies_e_diff = fMin(newEnergies_e_diff, DFRACT_BITS-1);
+
+ for (i=start; i<YBufferWriteOffset; i++) {
+ energies_e_diff[i] = prevEnergies_e_diff;
+ }
+ for (i=YBufferWriteOffset; i<stop; i++) {
+ energies_e_diff[i] = newEnergies_e_diff;
+ }
/* Sum up energies of all QMF-timeslots for both halfs */
+ FDK_ASSERT(len1<=8); /* otherwise an overflow is possible */
+ FDK_ASSERT(len2<=8); /* otherwise an overflow is possible */
+ /* init with some energy to prevent division by zero
+ and to prevent splitting for very low levels */
+ accu1_init = scaleValue((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY))),-energies_e);
+ accu2_init = scaleValue((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY))),-energies_e);
+ accu1_init = fMult(accu1_init, (FIXP_DBL)len1<<((DFRACT_BITS-1)-NRG_SHIFT-1))<<1;
+ accu2_init = fMult(accu2_init, (FIXP_DBL)len2<<((DFRACT_BITS-1)-NRG_SHIFT-1))<<1;
+
for (j=0; j<nSfb; j++) {
- #define NRG_SCALE 3
- /* init with some energy to prevent division by zero
- and to prevent splitting for very low levels */
- accu1 = ((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY*8.0/32))) << fixMin(scaleEnergies[0],25))>>NRG_SCALE; /* complex init for compare with original version */
- accu2 = ((FL2FXCONST_DBL((1.0e6*NORM_QMF_ENERGY*8.0/32))) << fixMin(scaleEnergies[0],25))>>NRG_SCALE; /* can be simplified in dsp implementation */
+
+ accu1 = accu1_init;
+ accu2 = accu2_init;
+ accu_e = energies_e+3;
/* Sum up energies in first half */
for (i=start; i<border; i++) {
- accu1 += (Energies[i][j]>>NRG_SCALE);
+ accu1 += scaleValue(Energies[i][j], -energies_e_diff[i]);
}
/* Sum up energies in second half */
for (i=border; i<stop; i++) {
- accu2 += (Energies[i][j]>>NRG_SCALE);
+ accu2 += scaleValue(Energies[i][j], -energies_e_diff[i]);
}
/* Energy change in current band */
- tmp0 = CalcLdData(accu2);
- tmp1 = CalcLdData(accu1);
- tmp2 = (tmp0 - tmp1 + CalcLdData(len1)-CalcLdData(len2));
- delta = fixp_abs(fMult(tmp2, FL2FXCONST_DBL(0.6931471806f)));
+ #define LN2 FL2FXCONST_DBL(0.6931471806f) /* ln(2) */
+ tmp0 = fLog2(accu2, accu_e) - fLog2(accu1, accu_e);
+ tmp1 = fLog2((FIXP_DBL)len1, 31) - fLog2((FIXP_DBL)len2, 31);
+ delta = fMult(LN2, (tmp0 + tmp1));
+ delta = (FIXP_DBL)FDKabs( delta );
/* Weighting with amplitude ratio of this band */
- result = (EnergyTotal == FL2FXCONST_DBL(0.0f))
- ? FL2FXCONST_DBL(0.f)
- : FDKsbrEnc_LSI_divide_scale_fract( (accu1+accu2),
- (EnergyTotal>>NRG_SCALE)+(FIXP_DBL)1,
- (FIXP_DBL)MAXVAL_DBL >> fixMin(scaleEnergies[0],(DFRACT_BITS-1)) );
+ accu_e++;
+ accu1>>=1;
+ accu2>>=1;
+ if (accu_e & 1) {
+ accu_e++;
+ accu1>>=1;
+ accu2>>=1;
+ }
- delta_sum += (FIXP_DBL)(fMult(sqrtFixp(result), delta));
+ delta_sum += fMult(sqrtFixp(accu1+accu2), delta);
+ *result_e = ((accu_e>>1) + LD_DATA_SHIFT);
}
+ energyTotal_e+=1; /* for a defined square result exponent, the exponent has to be even */
+ EnergyTotal<<=1;
+ delta_sum = fMult(delta_sum, invSqrtNorm2(EnergyTotal, &tmp_e));
+ *result_e = *result_e + (tmp_e-(energyTotal_e>>1));
+
return fMult(delta_sum, pos_weight);
+
}
@@ -175,9 +231,12 @@ static FIXP_DBL spectralChange(FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FRE
*******************************************************************************
\brief Calculates total lowband energy
- The return value nrgTotal is scaled by the factor (1/32.0)
+ The input values Energies[0] (low-band) are scaled by the factor
+ 2^(14-*scaleEnergies[0])
+ The input values Energies[1] (high-band) are scaled by the factor
+ 2^(14-*scaleEnergies[1])
- \return total energy in the lowband
+ \return total energy in the lowband, scaled by the factor 2^19
*******************************************************************************/
static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
int *scaleEnergies,
@@ -194,6 +253,7 @@ static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
int ts,k;
/* Sum up lowband energy from one frame at offset tran_off */
+ /* freqBandTable[LORES] has MAX_FREQ_COEFFS/2 +1 coeefs max. */
for (ts=tran_offdiv2; ts<YBufferWriteOffset; ts++) {
for (k = 0; k < freqBandTable[0]; k++) {
accu1 += Energies[ts][k] >> 6;
@@ -201,12 +261,12 @@ static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
}
for (; ts<tran_offdiv2+(slots>>nrgSzShift); ts++) {
for (k = 0; k < freqBandTable[0]; k++) {
- accu2 += Energies[ts][k] >> 6;
+ accu2 += Energies[ts][k] >> 9;
}
}
- nrgTotal = ( (accu1 >> fixMin(scaleEnergies[0],(DFRACT_BITS-1)))
- + (accu2 >> fixMin(scaleEnergies[1],(DFRACT_BITS-1))) ) << (2);
+ nrgTotal = ( scaleValueSaturate(accu1, 1-scaleEnergies[0]) )
+ + ( scaleValueSaturate(accu2, 4-scaleEnergies[1]) );
return(nrgTotal);
}
@@ -222,21 +282,23 @@ static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies,
is 1 SBR-band. Therefore the data to be fed into the spectralChange
function is reduced.
- The values EnergiesM are scaled by the factor (1/32.0) and scaleEnergies[0]
- The return value nrgTotal is scaled by the factor (1/32.0)
+ The values EnergiesM are scaled by the factor (2^19-scaleEnergies[0]) for
+ slots<YBufferWriteOffset and by the factor (2^19-scaleEnergies[1]) for
+ slots>=YBufferWriteOffset.
- \return total energy in the highband
+ \return total energy in the highband, scaled by factor 2^19
*******************************************************************************/
static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */
INT *scaleEnergies,
+ INT YBufferWriteOffset,
FIXP_DBL EnergiesM[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS], /*!< Combined output */
UCHAR *RESTRICT freqBandTable,
INT nSfb,
INT sbrSlots,
INT timeStep)
{
- INT i,j,k,slotIn,slotOut,scale;
+ INT i,j,k,slotIn,slotOut,scale[2];
INT li,ui;
FIXP_DBL nrgTotal;
FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
@@ -245,7 +307,7 @@ static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */
combine QMF-bands to SBR-bands,
combine Left and Right channel */
for (slotOut=0; slotOut<sbrSlots; slotOut++) {
- slotIn = 2*slotOut;
+ slotIn = timeStep*slotOut;
for (j=0; j<nSfb; j++) {
accu = FL2FXCONST_DBL(0.0f);
@@ -262,19 +324,29 @@ static FIXP_DBL addHighbandEnergies(FIXP_DBL **RESTRICT Energies, /*!< input */
}
}
- scale = fixMin(8,scaleEnergies[0]); /* scale energies down before add up */
+ /* scale energies down before add up */
+ scale[0] = fixMin(8,scaleEnergies[0]);
+ scale[1] = fixMin(8,scaleEnergies[1]);
- if ((scaleEnergies[0]-1) > (DFRACT_BITS-1) )
+ if ((scaleEnergies[0]-scale[0]) > (DFRACT_BITS-1) || (scaleEnergies[1]-scale[0]) > (DFRACT_BITS-1))
nrgTotal = FL2FXCONST_DBL(0.0f);
else {
/* Now add all energies */
accu = FL2FXCONST_DBL(0.0f);
- for (slotOut=0; slotOut<sbrSlots; slotOut++) {
+
+ for (slotOut=0; slotOut<YBufferWriteOffset; slotOut++) {
+ for (j=0; j<nSfb; j++) {
+ accu += (EnergiesM[slotOut][j] >> scale[0]);
+ }
+ }
+ nrgTotal = accu >> (scaleEnergies[0]-scale[0]);
+
+ for (slotOut=YBufferWriteOffset; slotOut<sbrSlots; slotOut++) {
for (j=0; j<nSfb; j++) {
- accu += (EnergiesM[slotOut][j] >> scale);
+ accu += (EnergiesM[slotOut][j] >> scale[0]);
}
}
- nrgTotal = accu >> (scaleEnergies[0]-scale);
+ nrgTotal = accu >> (scaleEnergies[1]-scale[1]);
}
return(nrgTotal);
@@ -299,18 +371,23 @@ FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
int YBufferSzShift,
int nSfb,
int timeStep,
- int no_cols)
+ int no_cols,
+ FIXP_DBL* tonality)
{
if (tran_vector[1]==0) /* no transient was detected */
{
FIXP_DBL delta;
- FIXP_DBL EnergiesM[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS];
+ INT delta_e;
+ FIXP_DBL (*EnergiesM)[MAX_FREQ_COEFFS];
FIXP_DBL EnergyTotal,newLowbandEnergy,newHighbandEnergy;
INT border;
INT sbrSlots = fMultI(GetInvInt(timeStep),no_cols);
+ C_ALLOC_SCRATCH_START(_EnergiesM, FIXP_DBL, NUMBER_TIME_SLOTS_2304*MAX_FREQ_COEFFS)
FDK_ASSERT( sbrSlots * timeStep == no_cols );
+ EnergiesM = (FIXP_DBL(*)[MAX_FREQ_COEFFS])_EnergiesM;
+
/*
Get Lowband-energy over a range of 2 frames (Look half a frame back and ahead).
*/
@@ -324,16 +401,13 @@ FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
newHighbandEnergy = addHighbandEnergies(Energies,
scaleEnergies,
+ YBufferWriteOffset,
EnergiesM,
freqBandTable,
nSfb,
sbrSlots,
timeStep);
- if ( h_sbrTransientDetector->frameShift != 0 ) {
- if (tran_vector[1]==0)
- tran_vector[0] = 0;
- } else
{
/* prevLowBandEnergy: Corresponds to 1 frame, starting with half a frame look-behind
newLowbandEnergy: Corresponds to 1 frame, starting in the middle of the current frame */
@@ -343,23 +417,39 @@ FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
of a FIXFIX-frame with 2 envelopes. */
border = (sbrSlots+1) >> 1;
+ if ( (INT)EnergyTotal&0xffffffe0 && (scaleEnergies[0]<32 || scaleEnergies[1]<32) ) /* i.e. > 31 */ {
delta = spectralChange(EnergiesM,
scaleEnergies,
EnergyTotal,
nSfb,
0,
border,
- sbrSlots);
+ YBufferWriteOffset,
+ sbrSlots,
+ &delta_e
+ );
+ } else {
+ delta = FL2FXCONST_DBL(0.0f);
+ delta_e = 0;
+
+ /* set tonality to 0 when energy is very low, since the amplitude
+ resolution should then be low as well */
+ *tonality = FL2FXCONST_DBL(0.0f);
+ }
+
- if (delta > (h_sbrTransientDetector->split_thr >> LD_DATA_SHIFT)) /* delta scaled by 1/64 */
+ if ( fIsLessThan(h_sbrTransientDetector->split_thr_m, h_sbrTransientDetector->split_thr_e, delta, delta_e) ) {
tran_vector[0] = 1; /* Set flag for splitting */
- else
+ } else {
tran_vector[0] = 0;
+ }
+
}
/* Update prevLowBandEnergy */
h_sbrTransientDetector->prevLowBandEnergy = newLowbandEnergy;
h_sbrTransientDetector->prevHighBandEnergy = newHighbandEnergy;
+ C_ALLOC_SCRATCH_END(_EnergiesM, FIXP_DBL, NUMBER_TIME_SLOTS_2304*MAX_FREQ_COEFFS)
}
}
@@ -636,6 +726,7 @@ FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTran,
int
FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
+ UINT sbrSyntaxFlags, /* SBR syntax flags derived from AOT. */
INT frameSize,
INT sampleFreq,
sbrConfigurationPtr params,
@@ -649,8 +740,8 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
{
INT totalBitrate = params->codecSettings.standardBitrate * params->codecSettings.nChannels;
INT codecBitrate = params->codecSettings.bitRate;
- FIXP_DBL bitrateFactor_fix, framedur_fix;
- INT scale_0, scale_1;
+ FIXP_DBL bitrateFactor_m, framedur_fix;
+ INT bitrateFactor_e, tmp_e;
FDKmemclear(h_sbrTransientDetector,sizeof(SBR_TRANSIENT_DETECTOR));
@@ -658,11 +749,12 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
h_sbrTransientDetector->tran_off = tran_off;
if(codecBitrate) {
- bitrateFactor_fix = fDivNorm((FIXP_DBL)totalBitrate, (FIXP_DBL)(codecBitrate<<2),&scale_0);
+ bitrateFactor_m = fDivNorm((FIXP_DBL)totalBitrate, (FIXP_DBL)(codecBitrate<<2),&bitrateFactor_e);
+ bitrateFactor_e += 2;
}
else {
- bitrateFactor_fix = FL2FXCONST_DBL(1.0/4.0);
- scale_0 = 0;
+ bitrateFactor_m = FL2FXCONST_DBL(1.0/4.0);
+ bitrateFactor_e = 2;
}
framedur_fix = fDivNorm(frameSize, sampleFreq);
@@ -674,9 +766,13 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
FIXP_DBL tmp = framedur_fix - FL2FXCONST_DBL(0.010);
tmp = fixMax(tmp, FL2FXCONST_DBL(0.0001));
- tmp = fDivNorm(FL2FXCONST_DBL(0.000075), fPow2(tmp), &scale_1);
+ tmp = fDivNorm(FL2FXCONST_DBL(0.000075), fPow2(tmp), &tmp_e);
+
+ bitrateFactor_e = (tmp_e + bitrateFactor_e);
- scale_1 = -(scale_1 + scale_0 + 2);
+ if(sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
+ bitrateFactor_e--; /* divide by 2 */
+ }
FDK_ASSERT(no_cols <= QMF_MAX_TIME_SLOTS);
FDK_ASSERT(no_rows <= QMF_CHANNELS);
@@ -684,14 +780,8 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
h_sbrTransientDetector->no_cols = no_cols;
h_sbrTransientDetector->tran_thr = (FIXP_DBL)((params->tran_thr << (32-24-1)) / no_rows);
h_sbrTransientDetector->tran_fc = tran_fc;
-
- if (scale_1>=0) {
- h_sbrTransientDetector->split_thr = fMult(tmp, bitrateFactor_fix) >> scale_1;
- }
- else {
- h_sbrTransientDetector->split_thr = fMult(tmp, bitrateFactor_fix) << (-scale_1);
- }
-
+ h_sbrTransientDetector->split_thr_m = fMult(tmp, bitrateFactor_m);
+ h_sbrTransientDetector->split_thr_e = bitrateFactor_e;
h_sbrTransientDetector->no_rows = no_rows;
h_sbrTransientDetector->mode = params->tran_det_mode;
h_sbrTransientDetector->prevLowBandEnergy = FL2FXCONST_DBL(0.0f);
@@ -699,3 +789,281 @@ FDKsbrEnc_InitSbrTransientDetector(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientD
return (0);
}
+
+#define ENERGY_SCALING_SIZE 32
+
+INT FDKsbrEnc_InitSbrFastTransientDetector(
+ HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
+ const INT time_slots_per_frame,
+ const INT bandwidth_qmf_slot,
+ const INT no_qmf_channels,
+ const INT sbr_qmf_1st_band
+ )
+{
+
+ int i, e;
+ int buff_size;
+ FIXP_DBL myExp;
+ FIXP_DBL myExpSlot;
+
+ h_sbrFastTransientDetector->lookahead = TRAN_DET_LOOKAHEAD;
+ h_sbrFastTransientDetector->nTimeSlots = time_slots_per_frame;
+
+ buff_size = h_sbrFastTransientDetector->nTimeSlots + h_sbrFastTransientDetector->lookahead;
+
+ for(i=0; i< buff_size; i++) {
+ h_sbrFastTransientDetector->delta_energy[i] = FL2FXCONST_DBL(0.0f);
+ h_sbrFastTransientDetector->energy_timeSlots[i] = FL2FXCONST_DBL(0.0f);
+ h_sbrFastTransientDetector->lowpass_energy[i] = FL2FXCONST_DBL(0.0f);
+ h_sbrFastTransientDetector->transientCandidates[i] = 0;
+ }
+
+ FDK_ASSERT(bandwidth_qmf_slot > 0.f);
+ h_sbrFastTransientDetector->stopBand = fMin(TRAN_DET_STOP_FREQ/bandwidth_qmf_slot, no_qmf_channels);
+ h_sbrFastTransientDetector->startBand = fMin(sbr_qmf_1st_band, h_sbrFastTransientDetector->stopBand - TRAN_DET_MIN_QMFBANDS);
+
+ FDK_ASSERT(h_sbrFastTransientDetector->startBand < no_qmf_channels);
+ FDK_ASSERT(h_sbrFastTransientDetector->startBand < h_sbrFastTransientDetector->stopBand);
+ FDK_ASSERT(h_sbrFastTransientDetector->startBand > 1);
+ FDK_ASSERT(h_sbrFastTransientDetector->stopBand > 1);
+
+ /* the energy weighting and adding up has a headroom of 6 Bits,
+ so up to 64 bands can be added without potential overflow. */
+ FDK_ASSERT(h_sbrFastTransientDetector->stopBand - h_sbrFastTransientDetector->startBand <= 64);
+
+ /* QMF_HP_dB_SLOPE_FIX says that we want a 20 dB per 16 kHz HP filter.
+ The following lines map this to the QMF bandwidth. */
+ #define EXP_E 7 /* QMF_CHANNELS (=64) multiplications max, max. allowed sum is 0.5 */
+ myExp = fMultNorm(QMF_HP_dBd_SLOPE_FIX, (FIXP_DBL)bandwidth_qmf_slot, &e);
+ myExp = scaleValueSaturate(myExp, e+0+DFRACT_BITS-1-EXP_E);
+ myExpSlot = myExp;
+
+ for(i=0; i<QMF_CHANNELS; i++){
+ /* Calculate dBf over all qmf bands:
+ dBf = (10^(0.002266f/10*bw(slot)))^(band) =
+ = 2^(log2(10)*0.002266f/10*bw(slot)*band) =
+ = 2^(0.00075275f*bw(slot)*band) */
+
+ FIXP_DBL dBf_m; /* dBf mantissa */
+ INT dBf_e; /* dBf exponent */
+ INT tmp;
+
+ INT dBf_int; /* dBf integer part */
+ FIXP_DBL dBf_fract; /* dBf fractional part */
+
+ /* myExp*(i+1) = myExp_int - myExp_fract
+ myExp*(i+1) is split up here for better accuracy of CalcInvLdData(),
+ for its result can be split up into an integer and a fractional part */
+
+ /* Round up to next integer */
+ FIXP_DBL myExp_int = (myExpSlot & (FIXP_DBL)0xfe000000) + (FIXP_DBL)0x02000000;
+
+ /* This is the fractional part that needs to be substracted */
+ FIXP_DBL myExp_fract = myExp_int - myExpSlot;
+
+ /* Calc integer part */
+ dBf_int = CalcInvLdData(myExp_int);
+ /* The result needs to be re-scaled. The ld(myExp_int) had been scaled by EXP_E,
+ the CalcInvLdData expects the operand to be scaled by LD_DATA_SHIFT.
+ Therefore, the correctly scaled result is dBf_int^(2^(EXP_E-LD_DATA_SHIFT)),
+ which is dBf_int^2 */
+ dBf_int *= dBf_int;
+
+ /* Calc fractional part */
+ dBf_fract = CalcInvLdData(-myExp_fract);
+ /* The result needs to be re-scaled. The ld(myExp_fract) had been scaled by EXP_E,
+ the CalcInvLdData expects the operand to be scaled by LD_DATA_SHIFT.
+ Therefore, the correctly scaled result is dBf_fract^(2^(EXP_E-LD_DATA_SHIFT)),
+ which is dBf_fract^2 */
+ dBf_fract = fMultNorm(dBf_fract, dBf_fract, &tmp);
+
+ /* Get worst case scaling of multiplication result */
+ dBf_e = (DFRACT_BITS-1 - tmp) - CountLeadingBits(dBf_int);
+
+ /* Now multiply integer with fractional part of the result, thus resulting
+ in the overall accurate fractional result */
+ dBf_m = fMultNorm(dBf_int, dBf_fract, &e);
+ dBf_m = scaleValueSaturate(dBf_m, e+DFRACT_BITS-1+tmp-dBf_e);
+ myExpSlot += myExp;
+
+ /* Keep the results */
+ h_sbrFastTransientDetector->dBf_m[i] = dBf_m;
+ h_sbrFastTransientDetector->dBf_e[i] = dBf_e;
+
+ }
+
+ /* Make sure that dBf is greater than 1.0 (because it should be a highpass) */
+ /* ... */
+
+ return 0;
+}
+
+void FDKsbrEnc_fastTransientDetect(
+ const HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
+ const FIXP_DBL *const *Energies,
+ const int *const scaleEnergies,
+ const INT YBufferWriteOffset,
+ UCHAR *const tran_vector
+ )
+{
+ int timeSlot, band;
+
+ FIXP_DBL max_delta_energy; /* helper to store maximum energy ratio */
+ int max_delta_energy_scale; /* helper to store scale of maximum energy ratio */
+ int ind_max = 0; /* helper to store index of maximum energy ratio */
+ int isTransientInFrame = 0;
+
+ const int nTimeSlots = h_sbrFastTransientDetector->nTimeSlots;
+ const int lookahead = h_sbrFastTransientDetector->lookahead;
+ const int startBand = h_sbrFastTransientDetector->startBand;
+ const int stopBand = h_sbrFastTransientDetector->stopBand;
+
+ int * transientCandidates = h_sbrFastTransientDetector->transientCandidates;
+
+ FIXP_DBL * energy_timeSlots = h_sbrFastTransientDetector->energy_timeSlots;
+ int * energy_timeSlots_scale = h_sbrFastTransientDetector->energy_timeSlots_scale;
+
+ FIXP_DBL * delta_energy = h_sbrFastTransientDetector->delta_energy;
+ int * delta_energy_scale = h_sbrFastTransientDetector->delta_energy_scale;
+
+ const FIXP_DBL thr = TRAN_DET_THRSHLD;
+ const INT thr_scale = TRAN_DET_THRSHLD_SCALE;
+
+ /*reset transient info*/
+ tran_vector[2] = 0;
+
+ /* reset transient candidates */
+ FDKmemclear(transientCandidates+lookahead, nTimeSlots*sizeof(int));
+
+ for(timeSlot = lookahead; timeSlot < nTimeSlots + lookahead; timeSlot++) {
+ int i, norm;
+ FIXP_DBL tmpE = FL2FXCONST_DBL(0.0f);
+ int headroomEnSlot = DFRACT_BITS-1;
+
+ FIXP_DBL smallNRG = FL2FXCONST_DBL(1e-2f);
+ FIXP_DBL denominator;
+ INT denominator_scale;
+
+ /* determine minimum headroom of energy values for this timeslot */
+ for(band = startBand; band < stopBand; band++) {
+ int tmp_headroom = fNormz(Energies[timeSlot][band])-1;
+ if(tmp_headroom < headroomEnSlot){
+ headroomEnSlot = tmp_headroom;
+ }
+ }
+
+ for(i = 0, band = startBand; band < stopBand; band++, i++) {
+ /* energy is weighted by weightingfactor stored in dBf_m array */
+ /* dBf_m index runs from 0 to stopBand-startband */
+ /* energy shifted by calculated headroom for maximum precision */
+ FIXP_DBL weightedEnergy = fMult(Energies[timeSlot][band]<<headroomEnSlot, h_sbrFastTransientDetector->dBf_m[i]);
+
+ /* energy is added up */
+ /* shift by 6 to have a headroom for maximum 64 additions */
+ /* shift by dBf_e to handle weighting factor dependent scale factors */
+ tmpE += weightedEnergy >> (6 + (10 - h_sbrFastTransientDetector->dBf_e[i]));
+ }
+
+ /* store calculated energy for timeslot */
+ energy_timeSlots[timeSlot] = tmpE;
+
+ /* calculate overall scale factor for energy of this timeslot */
+ /* = original scale factor of energies (-scaleEnergies[0]+2*QMF_SCALE_OFFSET or -scaleEnergies[1]+2*QMF_SCALE_OFFSET */
+ /* depending on YBufferWriteOffset) */
+ /* + weighting factor scale (10) */
+ /* + adding up scale factor ( 6) */
+ /* - headroom of energy value (headroomEnSlot) */
+ if(timeSlot < YBufferWriteOffset){
+ energy_timeSlots_scale[timeSlot] = (-scaleEnergies[0]+2*QMF_SCALE_OFFSET) + (10+6) - headroomEnSlot;
+ } else {
+ energy_timeSlots_scale[timeSlot] = (-scaleEnergies[1]+2*QMF_SCALE_OFFSET) + (10+6) - headroomEnSlot;
+ }
+
+ /* Add a small energy to the denominator, thus making the transient
+ detection energy-dependent. Loud transients are being detected,
+ silent ones not. */
+
+ /* make sure that smallNRG does not overflow */
+ if ( -energy_timeSlots_scale[timeSlot-1] + 1 > 5 )
+ {
+ denominator = smallNRG;
+ denominator_scale = 0;
+ } else {
+ /* Leave an additional headroom of 1 bit for this addition. */
+ smallNRG = scaleValue(smallNRG, -(energy_timeSlots_scale[timeSlot-1] + 1));
+ denominator = (energy_timeSlots[timeSlot-1]>>1) + smallNRG;
+ denominator_scale = energy_timeSlots_scale[timeSlot-1]+1;
+ }
+
+ delta_energy[timeSlot] = fDivNorm(energy_timeSlots[timeSlot], denominator, &norm);
+ delta_energy_scale[timeSlot] = energy_timeSlots_scale[timeSlot] - denominator_scale + norm;
+ }
+
+ /*get transient candidates*/
+ /* For every timeslot, check if delta(E) exceeds the threshold. If it did,
+ it could potentially be marked as a transient candidate. However, the 2
+ slots before the current one must not be transients with an energy higher
+ than 1.4*E(current). If both aren't transients or if the energy of the
+ current timesolot is more than 1.4 times higher than the energy in the
+ last or the one before the last slot, it is marked as a transient.*/
+
+ FDK_ASSERT(lookahead >= 2);
+ for(timeSlot = lookahead; timeSlot < nTimeSlots + lookahead; timeSlot++) {
+ FIXP_DBL energy_cur_slot_weighted = fMult(energy_timeSlots[timeSlot],FL2FXCONST_DBL(1.0f/1.4f));
+ if( !fIsLessThan(delta_energy[timeSlot], delta_energy_scale[timeSlot], thr, thr_scale) &&
+ ( ((transientCandidates[timeSlot-2]==0) && (transientCandidates[timeSlot-1]==0)) ||
+ !fIsLessThan(energy_cur_slot_weighted, energy_timeSlots_scale[timeSlot], energy_timeSlots[timeSlot-1], energy_timeSlots_scale[timeSlot-1] ) ||
+ !fIsLessThan(energy_cur_slot_weighted, energy_timeSlots_scale[timeSlot], energy_timeSlots[timeSlot-2], energy_timeSlots_scale[timeSlot-2] )
+ )
+ )
+{
+ /* in case of strong transients, subsequent
+ * qmf slots might be recognized as transients. */
+ transientCandidates[timeSlot] = 1;
+ }
+ }
+
+ /*get transient with max energy*/
+ max_delta_energy = FL2FXCONST_DBL(0.0f);
+ max_delta_energy_scale = 0;
+ ind_max = 0;
+ isTransientInFrame = 0;
+ for(timeSlot = 0; timeSlot < nTimeSlots; timeSlot++) {
+ int scale = fMax(delta_energy_scale[timeSlot], max_delta_energy_scale);
+ if(transientCandidates[timeSlot] && ( (delta_energy[timeSlot] >> (scale - delta_energy_scale[timeSlot])) > (max_delta_energy >> (scale - max_delta_energy_scale)) ) ) {
+ max_delta_energy = delta_energy[timeSlot];
+ max_delta_energy_scale = scale;
+ ind_max = timeSlot;
+ isTransientInFrame = 1;
+ }
+ }
+
+ /*from all transient candidates take the one with the biggest energy*/
+ if(isTransientInFrame) {
+ tran_vector[0] = ind_max;
+ tran_vector[1] = 1;
+ } else {
+ /*reset transient info*/
+ tran_vector[0] = tran_vector[1] = 0;
+ }
+
+ /*check for transients in lookahead*/
+ for(timeSlot = nTimeSlots; timeSlot < nTimeSlots + lookahead; timeSlot++) {
+ if(transientCandidates[timeSlot]) {
+ tran_vector[2] = 1;
+ }
+ }
+
+ /*update buffers*/
+ for(timeSlot = 0; timeSlot < lookahead; timeSlot++) {
+ transientCandidates[timeSlot] = transientCandidates[nTimeSlots + timeSlot];
+
+ /* fixpoint stuff */
+ energy_timeSlots[timeSlot] = energy_timeSlots[nTimeSlots + timeSlot];
+ energy_timeSlots_scale[timeSlot] = energy_timeSlots_scale[nTimeSlots + timeSlot];
+
+ delta_energy[timeSlot] = delta_energy[nTimeSlots + timeSlot];
+ delta_energy_scale[timeSlot] = delta_energy_scale[nTimeSlots + timeSlot];
+ }
+}
+
diff --git a/libSBRenc/src/tran_det.h b/libSBRenc/src/tran_det.h
index 95b5d2e..6fe1023 100644
--- a/libSBRenc/src/tran_det.h
+++ b/libSBRenc/src/tran_det.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -96,7 +96,8 @@ typedef struct
FIXP_DBL transients[QMF_MAX_TIME_SLOTS+(QMF_MAX_TIME_SLOTS/2)];
FIXP_DBL thresholds[QMF_CHANNELS];
FIXP_DBL tran_thr; /* Master threshold for transient signals */
- FIXP_DBL split_thr; /* Threshold for splitting FIXFIX-frames into 2 env */
+ FIXP_DBL split_thr_m; /* Threshold for splitting FIXFIX-frames into 2 env */
+ INT split_thr_e; /* Scale for splitting threshold */
FIXP_DBL prevLowBandEnergy; /* Energy of low band */
FIXP_DBL prevHighBandEnergy; /* Energy of high band */
INT tran_fc; /* Number of lowband subbands to discard */
@@ -112,6 +113,57 @@ SBR_TRANSIENT_DETECTOR;
typedef SBR_TRANSIENT_DETECTOR *HANDLE_SBR_TRANSIENT_DETECTOR;
+#define TRAN_DET_LOOKAHEAD 2
+#define TRAN_DET_START_FREQ 4500 /*start frequency for transient detection*/
+#define TRAN_DET_STOP_FREQ 13500 /*stop frequency for transient detection*/
+#define TRAN_DET_MIN_QMFBANDS 4 /* minimum qmf bands for transient detection */
+#define QMF_HP_dBd_SLOPE_FIX FL2FXCONST_DBL(0.00075275f) /* 0.002266f/10 * log2(10) */
+#define TRAN_DET_THRSHLD FL2FXCONST_DBL(3.2f/4.f)
+#define TRAN_DET_THRSHLD_SCALE (2)
+
+typedef struct
+{
+ INT transientCandidates[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
+ INT nTimeSlots;
+ INT lookahead;
+ INT startBand;
+ INT stopBand;
+
+ FIXP_DBL dBf_m[QMF_CHANNELS];
+ INT dBf_e[QMF_CHANNELS];
+
+ FIXP_DBL energy_timeSlots[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
+ INT energy_timeSlots_scale[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
+
+ FIXP_DBL delta_energy[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
+ INT delta_energy_scale[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
+
+ FIXP_DBL lowpass_energy[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
+ INT lowpass_energy_scale[QMF_MAX_TIME_SLOTS + TRAN_DET_LOOKAHEAD];
+#if defined (FTD_LOG)
+ FDKFILE *ftd_log;
+#endif
+}
+FAST_TRAN_DETECTOR;
+typedef FAST_TRAN_DETECTOR *HANDLE_FAST_TRAN_DET;
+
+
+INT FDKsbrEnc_InitSbrFastTransientDetector(
+ HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
+ const INT time_slots_per_frame,
+ const INT bandwidth_qmf_slot,
+ const INT no_qmf_channels,
+ const INT sbr_qmf_1st_band
+ );
+
+void FDKsbrEnc_fastTransientDetect(
+ const HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector,
+ const FIXP_DBL *const *Energies,
+ const int *const scaleEnergies,
+ const INT YBufferWriteOffset,
+ UCHAR *const tran_vector
+ );
+
void
FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
FIXP_DBL **Energies,
@@ -124,6 +176,7 @@ FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
int
FDKsbrEnc_InitSbrTransientDetector (HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector,
+ UINT sbrSyntaxFlags, /* SBR syntax flags derived from AOT. */
INT frameSize,
INT sampleFreq,
sbrConfigurationPtr params,
@@ -145,6 +198,6 @@ FDKsbrEnc_frameSplitter(FIXP_DBL **Energies,
int YBufferSzShift,
int nSfb,
int timeStep,
- int no_cols);
-
+ int no_cols,
+ FIXP_DBL* tonality);
#endif
diff --git a/libSYS/include/FDK_audio.h b/libSYS/include/FDK_audio.h
index 0660f4c..98ded3b 100644
--- a/libSYS/include/FDK_audio.h
+++ b/libSYS/include/FDK_audio.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -134,13 +134,7 @@ typedef enum
TT_MP4_LOAS = 10, /**< Audio Sync Stream. */
- TT_DRM = 12, /**< Digital Radio Mondial (DRM30/DRM+) bitstream format. */
-
- TT_MP1_L1 = 16, /**< MPEG 1 Audio Layer 1 audio bitstream. */
- TT_MP1_L2 = 17, /**< MPEG 1 Audio Layer 2 audio bitstream. */
- TT_MP1_L3 = 18, /**< MPEG 1 Audio Layer 3 audio bitstream. */
-
- TT_RSVD50 = 50 /**< */
+ TT_DRM = 12 /**< Digital Radio Mondial (DRM30/DRM+) bitstream format. */
} TRANSPORT_TYPE;
@@ -203,38 +197,22 @@ typedef enum
AOT_SAOC = 43, /**< SAOC */
AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */
- AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */
-
/* Pseudo AOTs */
- AOT_MP2_AAC_MAIN = 128, /**< Virtual AOT MP2 Main profile */
- AOT_MP2_AAC_LC = 129, /**< Virtual AOT MP2 Low Complexity profile */
- AOT_MP2_AAC_SSR = 130, /**< Virtual AOT MP2 Scalable Sampling Rate profile */
-
- AOT_MP2_SBR = 132, /**< Virtual AOT MP2 Low Complexity Profile with SBR */
-
- AOT_DAB = 134, /**< Virtual AOT for DAB (Layer2 with scalefactor CRC) */
- AOT_DABPLUS_AAC_LC = 135, /**< Virtual AOT for DAB plus AAC-LC */
- AOT_DABPLUS_SBR = 136, /**< Virtual AOT for DAB plus HE-AAC */
- AOT_DABPLUS_PS = 137, /**< Virtual AOT for DAB plus HE-AAC v2 */
-
- AOT_PLAIN_MP1 = 140, /**< Virtual AOT for plain mp1 */
- AOT_PLAIN_MP2 = 141, /**< Virtual AOT for plain mp2 */
- AOT_PLAIN_MP3 = 142, /**< Virtual AOT for plain mp3 */
-
AOT_DRM_AAC = 143, /**< Virtual AOT for DRM (ER-AAC-SCAL without SBR) */
AOT_DRM_SBR = 144, /**< Virtual AOT for DRM (ER-AAC-SCAL with SBR) */
- AOT_DRM_MPEG_PS = 145, /**< Virtual AOT for DRM (ER-AAC-SCAL with SBR and MPEG-PS) */
- AOT_DRM_SURROUND = 146, /**< Virtual AOT for DRM Surround (ER-AAC-SCAL (+SBR) +MPS) */
-
- AOT_MP2_PS = 156, /**< Virtual AOT MP2 Low Complexity Profile with SBR and PS */
-
- AOT_MPEGS_RESIDUALS = 256 /**< Virtual AOT for MPEG Surround residuals */
+ AOT_DRM_MPEG_PS = 145 /**< Virtual AOT for DRM (ER-AAC-SCAL with SBR and MPEG-PS) */
} AUDIO_OBJECT_TYPE;
+#define CAN_DO_PS(aot) \
+ ((aot) == AOT_AAC_LC \
+|| (aot) == AOT_SBR \
+|| (aot) == AOT_PS \
+|| (aot) == AOT_ER_BSAC \
+|| (aot) == AOT_DRM_AAC)
+
#define IS_USAC(aot) \
- ((aot) == AOT_USAC \
-|| (aot) == AOT_RSVD50)
+ ((aot) == AOT_USAC)
#define IS_LOWDELAY(aot) \
((aot) == AOT_ER_AAC_LD \
diff --git a/libSYS/src/genericStds.cpp b/libSYS/src/genericStds.cpp
index affa90b..89c422c 100644
--- a/libSYS/src/genericStds.cpp
+++ b/libSYS/src/genericStds.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -99,7 +99,7 @@ amm-info@iis.fraunhofer.de
/* library info */
#define SYS_LIB_VL0 1
#define SYS_LIB_VL1 3
-#define SYS_LIB_VL2 6
+#define SYS_LIB_VL2 8
#define SYS_LIB_TITLE "System Integration Library"
#ifdef __ANDROID__
#define SYS_LIB_BUILD_DATE ""