aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--README.md27
-rwxr-xr-xbootstrap4
-rw-r--r--libAACenc/include/aacenc_lib.h2
-rw-r--r--libAACenc/src/aacenc.cpp32
-rw-r--r--libAACenc/src/aacenc_lib.cpp108
-rw-r--r--libAACenc/src/aacenc_tns.cpp19
-rw-r--r--libAACenc/src/bitenc.cpp56
-rw-r--r--libAACenc/src/dyn_bits.cpp2
-rw-r--r--libAACenc/src/psy_configuration.cpp180
-rw-r--r--libAACenc/src/psy_const.h1
-rw-r--r--libAACenc/src/qc_main.cpp3
-rw-r--r--libFDK/src/FDK_crc.cpp49
-rw-r--r--libFDK/src/FDK_tools_rom.cpp3
-rw-r--r--libFDK/src/mdct.cpp3
-rw-r--r--libMpegTPEnc/src/tpenc_dab.cpp467
-rw-r--r--libMpegTPEnc/src/tpenc_dab.h217
-rw-r--r--libMpegTPEnc/src/tpenc_lib.cpp51
-rw-r--r--libSBRenc/src/env_est.cpp1
-rw-r--r--libSBRenc/src/sbr_encoder.cpp2
-rw-r--r--libSYS/include/FDK_audio.h16
21 files changed, 1210 insertions, 36 deletions
diff --git a/Makefile.am b/Makefile.am
index fe6b867..2e78a3f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -161,7 +161,8 @@ MPEGTPENC_SRC = \
libMpegTPEnc/src/tpenc_adts.cpp \
libMpegTPEnc/src/tpenc_asc.cpp \
libMpegTPEnc/src/tpenc_latm.cpp \
- libMpegTPEnc/src/tpenc_lib.cpp
+ libMpegTPEnc/src/tpenc_lib.cpp \
+ libMpegTPEnc/src/tpenc_dab.cpp
PCMUTILS_SRC = \
libPCMutils/src/limiter.cpp \
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c114e87
--- /dev/null
+++ b/README.md
@@ -0,0 +1,27 @@
+A patched version of fdk-aac with DAB+ support
+==============================================
+
+This is a modified version of fdk-aac that supports the AOTs
+required for DAB+ encoding.
+
+This library is a dependency for [ODR-AudioEnc](https://github.com/Opendigitalradio/ODR-AudioEnc)
+
+See http://www.opendigitalradio.org for more
+
+Branches in this repository
+===========================
+
+The dabplus branch points to a version that builds `libfdk-aac.so.1`.
+The dabplus2 branch points to a version that builds `libfdk-aac.so.2`.
+
+Installation
+============
+
+Make sure you have installed git, build-essential and automake, otherwise install them with `sudo apt-get install git build-essential automake`.
+
+ $ git clone https://github.com/Opendigitalradio/fdk-aac.git
+ $ cd fdk-aac/
+ $ ./bootstrap
+ $ ./configure
+ $ make
+ $ sudo make install
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 0000000..a3394ab
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,4 @@
+#! /bin/sh
+
+autoreconf --install && \
+ echo "You can call ./configure now"
diff --git a/libAACenc/include/aacenc_lib.h b/libAACenc/include/aacenc_lib.h
index fa41ee6..231bbb4 100644
--- a/libAACenc/include/aacenc_lib.h
+++ b/libAACenc/include/aacenc_lib.h
@@ -1340,6 +1340,7 @@ typedef enum {
AACENC_GRANULE_LENGTH =
0x0105, /*!< Core encoder (AAC) audio frame length in samples:
- 1024: Default configuration.
+ - 960: DRM/DAB+.
- 512: Default length in LD/ELD configuration.
- 480: Length in LD/ELD configuration.
- 256: Length for ELD reduced delay mode (x2).
@@ -1503,6 +1504,7 @@ typedef enum {
0x0303, /*!< Number of sub frames in a transport frame for LOAS/LATM or
ADTS (default 1).
- ADTS: Maximum number of sub frames restricted to 4.
+ - DAB+: Maximum number of sub frames restricted to 6.
- LOAS/LATM: Maximum number of sub frames restricted to 2.*/
AACENC_AUDIOMUXVER =
diff --git a/libAACenc/src/aacenc.cpp b/libAACenc/src/aacenc.cpp
index 8b8a1ad..372df31 100644
--- a/libAACenc/src/aacenc.cpp
+++ b/libAACenc/src/aacenc.cpp
@@ -186,6 +186,7 @@ INT FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc, AUDIO_OBJECT_TYPE aot,
} while (prevBitRate != bitRate && iter++ < 3);
+ //fprintf(stderr, "FDKaacEnc_LimitBitrate(): bitRate=%d\n", bitRate);
return bitRate;
}
@@ -431,6 +432,36 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(
return AAC_ENC_UNSUPPORTED_BITRATE;
}
+ INT superframe_size = 110*8*(config->bitRate/8000);
+ INT frames_per_superframe = 6;
+ INT staticBits = 0;
+ if((config->syntaxFlags & AC_DAB) && hTpEnc) {
+ staticBits = transportEnc_GetStaticBits(hTpEnc, 0);
+ switch(config->sampleRate) {
+ case 48000:
+ frames_per_superframe=6;
+ break;
+ case 32000:
+ frames_per_superframe=4;
+ break;
+ case 24000:
+ frames_per_superframe=3;
+ break;
+ case 16000:
+ frames_per_superframe=2;
+ break;
+ }
+
+ //config->nSubFrames = frames_per_superframe;
+ //fprintf(stderr, "DAB+ superframe size=%d\n", superframe_size);
+ config->bitRate = (superframe_size - 16*(frames_per_superframe-1) - staticBits) * 1000/120;
+ //fprintf(stderr, "DAB+ tuned bitrate=%d\n", config->bitRate);
+ config->maxBitsPerFrame = (superframe_size - 16*(frames_per_superframe-1) - staticBits) / frames_per_superframe;
+ config->maxBitsPerFrame += 7; /*padding*/
+ //config->bitreservoir=(superframe_size - 16*(frames_per_superframe-1) - staticBits - 2*8)/frames_per_superframe;
+ //fprintf(stderr, "DAB+ tuned maxBitsPerFrame=%d\n", (superframe_size - 16*(frames_per_superframe-1) - staticBits)/frames_per_superframe);
+ }
+
/* check bit rate */
if (FDKaacEnc_LimitBitrate(
@@ -454,6 +485,7 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(
/* check frame length */
switch (config->framelength) {
case 1024:
+ case 960:
if (isLowDelay(config->audioObjectType)) {
return AAC_ENC_INVALID_FRAME_LENGTH;
}
diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp
index b10fa84..4eaa662 100644
--- a/libAACenc/src/aacenc_lib.cpp
+++ b/libAACenc/src/aacenc_lib.cpp
@@ -99,7 +99,7 @@ amm-info@iis.fraunhofer.de
Description: FDK HE-AAC Encoder interface library functions
*******************************************************************************/
-
+#include <stdio.h>
#include "aacenc_lib.h"
#include "FDK_audio.h"
#include "aacenc.h"
@@ -368,7 +368,9 @@ static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig) {
* AOT_AAC_LC */
if ((hAacConfig->audioObjectType == AOT_SBR) ||
(hAacConfig->audioObjectType == AOT_PS) ||
- (hAacConfig->audioObjectType == AOT_MP2_SBR)) {
+ (hAacConfig->audioObjectType == AOT_MP2_SBR) ||
+ (hAacConfig->audioObjectType == AOT_DABPLUS_SBR) ||
+ (hAacConfig->audioObjectType == AOT_DABPLUS_PS)) {
sbrUsed = 1;
}
if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD &&
@@ -382,9 +384,10 @@ static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig) {
static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType) {
INT psUsed = 0;
- if (audioObjectType == AOT_PS) {
- psUsed = 1;
- }
+ if ((audioObjectType == AOT_PS) ||
+ (audioObjectType == AOT_DABPLUS_PS)) {
+ psUsed = 1;
+ }
return (psUsed);
}
@@ -417,7 +420,9 @@ static SBR_PS_SIGNALING getSbrSignalingMode(
if ((audioObjectType == AOT_AAC_LC) || (audioObjectType == AOT_SBR) ||
(audioObjectType == AOT_PS) || (audioObjectType == AOT_MP2_AAC_LC) ||
- (audioObjectType == AOT_MP2_SBR)) {
+ (audioObjectType == AOT_MP2_SBR) ||
+ (audioObjectType == AOT_DABPLUS_SBR) ||
+ (audioObjectType == AOT_DABPLUS_PS)) {
switch (transportType) {
case TT_MP4_ADIF:
case TT_MP4_ADTS:
@@ -472,11 +477,17 @@ static void FDKaacEnc_MapConfig(CODER_CONFIG *const cc,
/* Map virtual aot to transport aot. */
switch (hAacConfig->audioObjectType) {
case AOT_MP2_AAC_LC:
+ case AOT_DABPLUS_AAC_LC:
transport_AOT = AOT_AAC_LC;
break;
case AOT_MP2_SBR:
+ case AOT_DABPLUS_SBR:
transport_AOT = AOT_SBR;
cc->flags |= CC_SBR;
+ break;
+ case AOT_DABPLUS_PS:
+ transport_AOT = AOT_PS;
+ cc->flags |= CC_SBR;
break;
default:
transport_AOT = hAacConfig->audioObjectType;
@@ -525,9 +536,27 @@ static void FDKaacEnc_MapConfig(CODER_CONFIG *const cc,
cc->flags |= CC_IS_BASELAYER;
cc->channelMode = hAacConfig->channelMode;
- cc->nSubFrames = (hAacConfig->nSubFrames > 1 && extCfg->userTpNsubFrames == 1)
+if (extCfg->userTpType == TT_DABPLUS && hAacConfig->nSubFrames==1) {
+ switch(hAacConfig->sampleRate) {
+ case 48000:
+ cc->nSubFrames=6;
+ break;
+ case 32000:
+ cc->nSubFrames=4;
+ break;
+ case 24000:
+ cc->nSubFrames=3;
+ break;
+ case 16000:
+ cc->nSubFrames=2;
+ break;
+ }
+ //fprintf(stderr, "hAacConfig->nSubFrames=%d hAacConfig->sampleRate=%d\n", hAacConfig->nSubFrames, hAacConfig->sampleRate);
+ } else {
+ cc->nSubFrames = (hAacConfig->nSubFrames > 1 && extCfg->userTpNsubFrames == 1)
? hAacConfig->nSubFrames
: extCfg->userTpNsubFrames;
+ }
cc->flags |= (extCfg->userTpProtection) ? CC_PROTECTION : 0;
@@ -805,6 +834,7 @@ static INT aacEncoder_LimitBitrate(const HANDLE_TRANSPORTENC hTpEnc,
bitRate);
}
+ //fprintf(stderr, "aacEncoder_LimitBitrate(): bitRate=%d\n", bitRate);
return bitRate;
}
@@ -920,6 +950,21 @@ static AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
return AACENC_INVALID_CONFIG;
}
break;
+
+ case AOT_DABPLUS_SBR:
+ case AOT_DABPLUS_PS:
+ hAacConfig->syntaxFlags |= ((config->userSbrEnabled) ? AC_SBR_PRESENT : 0);
+ case AOT_DABPLUS_AAC_LC:
+ config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_DABPLUS;
+ hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 960;
+ if (hAacConfig->framelength != 960) {
+ return AACENC_INVALID_CONFIG;
+ }
+ config->userTpSignaling=2;
+ if(config->userTpType == TT_DABPLUS)
+ hAacConfig->syntaxFlags |= AC_DAB;
+ break;
+
case AOT_ER_AAC_LD:
hAacConfig->epConfig = 0;
hAacConfig->syntaxFlags |= AC_ER | AC_LD;
@@ -1144,7 +1189,23 @@ static AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
break;
}
- /* Configure PNS */
+#if 0 // TODO Is this still needed?
+ /* We need the frame length to call aacEncoder_LimitBitrate() */
+ hAacConfig->bitRate = aacEncoder_LimitBitrate(
+ NULL,
+ hAacConfig->sampleRate,
+ hAacConfig->framelength,
+ hAacConfig->nChannels,
+ hAacConfig->channelMode,
+ hAacConfig->bitRate,
+ hAacConfig->nSubFrames,
+ isSbrActive(hAacConfig),
+ hAacConfig->sbrRatio,
+ hAacConfig->audioObjectType
+ );
+#endif
+
+/* Configure PNS */
if (AACENC_BR_MODE_IS_VBR(hAacConfig->bitrateMode) /* VBR without PNS. */
|| (hAacConfig->useTns == 0)) /* TNS required. */
{
@@ -1561,7 +1622,7 @@ AACENC_ERROR aacEncOpen(HANDLE_AACENCODER *phAacEncoder, const UINT encModules,
hAacEncoder->outBufferInBytes =
1 << (DFRACT_BITS - CntLeadingZeros(fixMax(
1, ((1) * hAacEncoder->nMaxAacChannels * 6144) >>
- 3))); /* buffer has to be 2^n */
+ 2))); /* buffer has to be 2^n */
if (NULL == (hAacEncoder->outBuffer = (UCHAR *)FDKcalloc(
hAacEncoder->outBufferInBytes, sizeof(UCHAR)))) {
err = AACENC_MEMORY_ERROR;
@@ -2068,7 +2129,7 @@ AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info) {
LIB_VERSION_STRING(&info[i]);
/* Capability flags */
- info[i].flags = 0 | CAPF_AAC_1024 | CAPF_AAC_LC | CAPF_AAC_512 |
+ info[i].flags = 0 | CAPF_AAC_1024 | CAPF_AAC_LC | CAPF_AAC_960| CAPF_AAC_512 |
CAPF_AAC_480 | CAPF_AAC_DRC | CAPF_AAC_ELD_DOWNSCALE;
/* End of flags */
@@ -2093,6 +2154,7 @@ AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder,
/* check if AOT matches the allocated modules */
switch (value) {
case AOT_PS:
+ case AOT_DABPLUS_PS:
if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) {
err = AACENC_INVALID_CONFIG;
goto bail;
@@ -2100,6 +2162,7 @@ AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder,
FDK_FALLTHROUGH;
case AOT_SBR:
case AOT_MP2_SBR:
+ case AOT_DABPLUS_SBR:
if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) {
err = AACENC_INVALID_CONFIG;
goto bail;
@@ -2107,6 +2170,7 @@ AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder,
FDK_FALLTHROUGH;
case AOT_AAC_LC:
case AOT_MP2_AAC_LC:
+ case AOT_DABPLUS_AAC_LC:
case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD:
if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) {
@@ -2138,6 +2202,8 @@ AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder,
case 3:
case 4:
case 5:
+ case 7:
+ case 8:
settings->userBitrateMode = value;
hAacEncoder->InitFlags |=
AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT;
@@ -2224,6 +2290,7 @@ AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder,
if (settings->userFramelength != value) {
switch (value) {
case 1024:
+ case 960:
case 512:
case 480:
case 256:
@@ -2266,17 +2333,18 @@ AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder,
break;
case AACENC_TRANSMUX:
if (settings->userTpType != (TRANSPORT_TYPE)value) {
- TRANSPORT_TYPE type = (TRANSPORT_TYPE)value;
- UINT flags = hAacEncoder->CAPF_tpEnc;
+ TRANSPORT_TYPE type = (TRANSPORT_TYPE)value;
+ UINT flags = hAacEncoder->CAPF_tpEnc;
if (!(((type == TT_MP4_ADIF) && (flags & CAPF_ADIF)) ||
- ((type == TT_MP4_ADTS) && (flags & CAPF_ADTS)) ||
- ((type == TT_MP4_LATM_MCP0) &&
- ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) ||
- ((type == TT_MP4_LATM_MCP1) &&
- ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) ||
- ((type == TT_MP4_LOAS) && (flags & CAPF_LOAS)) ||
- ((type == TT_MP4_RAW) && (flags & CAPF_RAWPACKETS)))) {
+ ((type == TT_MP4_ADTS) && (flags & CAPF_ADTS)) ||
+ ((type == TT_MP4_LATM_MCP0) &&
+ ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) ||
+ ((type == TT_MP4_LATM_MCP1) &&
+ ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) ||
+ ((type == TT_MP4_LOAS) && (flags & CAPF_LOAS)) ||
+ ((type == TT_MP4_RAW) && (flags & CAPF_RAWPACKETS)) ||
+ ((type == TT_DABPLUS) && ((flags & CAPF_DAB_AAC) && (flags & CAPF_RAWPACKETS))) )) {
err = AACENC_INVALID_CONFIG;
break;
}
@@ -2326,7 +2394,7 @@ AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder,
break;
case AACENC_TPSUBFRAMES:
if (settings->userTpNsubFrames != value) {
- if (!((value >= 1) && (value <= 4))) {
+ if (!((value >= 1) && (value <= 6))) {
err = AACENC_INVALID_CONFIG;
break;
}
diff --git a/libAACenc/src/aacenc_tns.cpp b/libAACenc/src/aacenc_tns.cpp
index 4462600..3436150 100644
--- a/libAACenc/src/aacenc_tns.cpp
+++ b/libAACenc/src/aacenc_tns.cpp
@@ -196,6 +196,22 @@ static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab1024[] = {
{44100, {42, 14}}, {32000, {51, 14}}, {24000, {46, 14}}, {22050, {46, 14}},
{16000, {42, 14}}, {12000, {42, 14}}, {11025, {42, 14}}, {8000, {39, 14}}};
+static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab960[] =
+{
+ { 96000, { 31, 9}},
+ { 88200, { 31, 9}},
+ { 64000, { 34, 10}},
+ { 48000, { 49, 14}},
+ { 44100, { 49, 14}},
+ { 32000, { 49, 14}},
+ { 24000, { 46, 15}},
+ { 22050, { 46, 14}},
+ { 16000, { 46, 15}},
+ { 12000, { 42, 15}},
+ { 11025, { 42, 15}},
+ { 8000, { 40, 15}}
+};
+
static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab120[] = {
{48000, {12, -1}}, /* 48000 */
{44100, {12, -1}}, /* 44100 */
@@ -278,6 +294,9 @@ static INT getTnsMaxBands(const INT sampleRate, const INT granuleLength,
switch (granuleLength) {
case 960:
+ pMaxBandsTab = tnsMaxBandsTab960;
+ maxBandsTabSize = sizeof(tnsMaxBandsTab960) / sizeof(TNS_MAX_TAB_ENTRY);
+ break;
case 1024:
pMaxBandsTab = tnsMaxBandsTab1024;
maxBandsTabSize = sizeof(tnsMaxBandsTab1024) / sizeof(TNS_MAX_TAB_ENTRY);
diff --git a/libAACenc/src/bitenc.cpp b/libAACenc/src/bitenc.cpp
index 957e821..512d596 100644
--- a/libAACenc/src/bitenc.cpp
+++ b/libAACenc/src/bitenc.cpp
@@ -100,6 +100,7 @@ amm-info@iis.fraunhofer.de
*******************************************************************************/
+#include <stdio.h>
#include "bitenc.h"
#include "bit_cnt.h"
#include "dyn_bits.h"
@@ -1197,6 +1198,23 @@ AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,
frameBits = bitMarkUp = alignAnchor;
+
+ /* Write DSEs first in case of DAB */
+ for (n = 0; (n < qcOut->nExtensions) && (n < (2+2)); n++) {
+ if ( (syntaxFlags & AC_DAB) &&
+ (qcOut->extension[n].type == EXT_DATA_ELEMENT) ) {
+ FDKaacEnc_writeExtensionData( hTpEnc,
+ &qcOut->extension[n],
+ 0,
+ alignAnchor,
+ syntaxFlags,
+ aot,
+ epConfig );
+ }
+
+ /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here */
+ }
+
/* Channel element loop */
for (i = 0; i < channelMapping->nElements; i++) {
ELEMENT_INFO elInfo = channelMapping->elInfo[i];
@@ -1283,20 +1301,40 @@ AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,
n = qcOut->nExtensions;
/* Add fill data / stuffing bits */
- qcOut->extension[n].type = EXT_FILL_DATA;
- qcOut->extension[n].nPayloadBits = qcOut->totFillBits;
- qcOut->nExtensions++;
+ n = qcOut->nExtensions;
+
+// if (!(syntaxFlags & AC_DAB)) {
+ qcOut->extension[n].type = EXT_FILL_DATA;
+ qcOut->extension[n].nPayloadBits = qcOut->totFillBits;
+ qcOut->nExtensions++;
+// } else {
+// doByteAlign = 0;
+// }
+ if (syntaxFlags & AC_DAB)
+ doByteAlign = 0;
/* Write global extension payload and fill data */
- for (n = 0; (n < qcOut->nExtensions) && (n < (2 + 2)); n++) {
- FDKaacEnc_writeExtensionData(hTpEnc, &qcOut->extension[n], 0, alignAnchor,
- syntaxFlags, aot, epConfig);
+ for (n = 0; (n < qcOut->nExtensions) && (n < (2+2)); n++)
+ {
+ if ( !(syntaxFlags & AC_DAB) ||
+ ( (syntaxFlags & AC_DAB) &&
+ (qcOut->extension[n].type != EXT_DATA_ELEMENT)
+ )
+ ) {
+ FDKaacEnc_writeExtensionData( hTpEnc,
+ &qcOut->extension[n],
+ 0,
+ alignAnchor,
+ syntaxFlags,
+ aot,
+ epConfig );
+ }
/* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here
*/
}
- if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) {
+ if (!(syntaxFlags & (AC_SCALABLE | AC_ER | AC_DAB))) {
FDKwriteBits(hBs, ID_END, EL_ID_BITS);
}
@@ -1314,9 +1352,11 @@ AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,
transportEnc_EndAccessUnit(hTpEnc, &frameBits);
- if (frameBits != qcOut->totalBits + qcKernel->globHdrBits) {
+ if (frameBits != qcOut->totalBits + qcKernel->globHdrBits){
+ fprintf(stderr, "frameBits != qcOut->totalBits + qcKernel->globHdrBits: %d != %d + %d", frameBits, qcOut->totalBits, qcKernel->globHdrBits);
return AAC_ENC_WRITTEN_BITS_ERROR;
}
+ //fprintf(stderr, "ErrorStatus=%d", ErrorStatus);
return ErrorStatus;
}
diff --git a/libAACenc/src/dyn_bits.cpp b/libAACenc/src/dyn_bits.cpp
index 74baeb8..b52dc2e 100644
--- a/libAACenc/src/dyn_bits.cpp
+++ b/libAACenc/src/dyn_bits.cpp
@@ -363,6 +363,8 @@ static void FDKaacEnc_noiselessCounter(
break;
}
+ FDK_ASSERT(sideInfoTab != NULL);
+
sectionData->noOfSections = 0;
sectionData->huffmanBits = 0;
sectionData->sideInfoBits = 0;
diff --git a/libAACenc/src/psy_configuration.cpp b/libAACenc/src/psy_configuration.cpp
index eef90bc..b444b58 100644
--- a/libAACenc/src/psy_configuration.cpp
+++ b/libAACenc/src/psy_configuration.cpp
@@ -130,6 +130,161 @@ static const SFB_INFO_TAB sfbInfoTab[] = {
};
+
+
+const SFB_PARAM_LONG p_FDKaacEnc_8000_long_960 = {
+ 40,
+ { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16,
+ 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28,
+ 28, 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 16 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_8000_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_11025_long_960 = {
+ 42,
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24,
+ 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_11025_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_12000_long_960 = {
+ 42,
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24,
+ 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_12000_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_16000_long_960 = {
+ 42,
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24,
+ 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_16000_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_22050_long_960 = {
+ 46,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16,
+ 20, 20, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, 52, 52,
+ 64, 64, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_22050_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_24000_long_960 = {
+ 46,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16,
+ 20, 20, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, 52, 52,
+ 64, 64, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_24000_short_120 = {
+ 15,
+ { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 12 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_32000_long_960 = {
+ 49,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12,
+ 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32 }
+};
+
+const SFB_PARAM_SHORT p_FDKaacEnc_32000_short_120 = {
+ 14,
+ { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 8 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_44100_long_960 = {
+ 49,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
+ 8, 8, 8, 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28,
+ 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32 }
+};
+
+const SFB_PARAM_SHORT p_FDKaacEnc_44100_short_120 = {
+ 14,
+ { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 8 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_48000_long_960 = {
+ 49,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
+ 8, 8, 8, 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28,
+ 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_48000_short_120 = {
+ 14,
+ { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 8 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_64000_long_960 = {
+ 46,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12,
+ 12, 16, 16, 16, 20, 24, 24, 28, 36, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 16 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_64000_short_120 = {
+ 12,
+ { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 28 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_88200_long_960 = {
+ 40,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 12,
+ 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_88200_short_120 = {
+ 12,
+ { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 28 }
+};
+
+const SFB_PARAM_LONG p_FDKaacEnc_96000_long_960 = {
+ 40,
+ { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 12,
+ 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 }
+};
+const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_120 = {
+ 12,
+ { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 28 }
+};
+
+
+static const SFB_INFO_TAB sfbInfoTab960[] = {
+ { 8000, &p_FDKaacEnc_8000_long_960, &p_FDKaacEnc_8000_short_120},
+ {11025, &p_FDKaacEnc_11025_long_960, &p_FDKaacEnc_11025_short_120},
+ {12000, &p_FDKaacEnc_12000_long_960, &p_FDKaacEnc_12000_short_120},
+ {16000, &p_FDKaacEnc_16000_long_960, &p_FDKaacEnc_16000_short_120},
+ {22050, &p_FDKaacEnc_22050_long_960, &p_FDKaacEnc_22050_short_120},
+ {24000, &p_FDKaacEnc_24000_long_960, &p_FDKaacEnc_24000_short_120},
+ {32000, &p_FDKaacEnc_32000_long_960, &p_FDKaacEnc_32000_short_120},
+ {44100, &p_FDKaacEnc_44100_long_960, &p_FDKaacEnc_44100_short_120},
+ {48000, &p_FDKaacEnc_48000_long_960, &p_FDKaacEnc_48000_short_120},
+ {64000, &p_FDKaacEnc_64000_long_960, &p_FDKaacEnc_64000_short_120},
+ {88200, &p_FDKaacEnc_88200_long_960, &p_FDKaacEnc_88200_short_120},
+ {96000, &p_FDKaacEnc_96000_long_960, &p_FDKaacEnc_96000_short_120},
+};
+
+
/* 22050 and 24000 Hz */
static const SFB_PARAM_LONG p_22050_long_512 = {
31, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12,
@@ -204,10 +359,13 @@ AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(const LONG sampleRate,
*/
switch (granuleLength) {
case 1024:
- case 960:
sfbInfo = sfbInfoTab;
size = (INT)(sizeof(sfbInfoTab) / sizeof(SFB_INFO_TAB));
break;
+ case 960:
+ sfbInfo = sfbInfoTab960;
+ size = (INT)(sizeof(sfbInfoTab960)/sizeof(SFB_INFO_TAB));
+ break;
case 512:
sfbInfo = sfbInfoTabLD512;
size = sizeof(sfbInfoTabLD512);
@@ -287,23 +445,31 @@ static FIXP_DBL FDKaacEnc_BarcLineValue(INT noOfLines, INT fftLine,
center_freq = fftLine * samplingFreq; /* q11 or q8 */
+
switch (noOfLines) {
case 1024:
center_freq = center_freq << 2; /* q13 */
break;
+ case 960:
+ center_freq = fMult(center_freq, INV480) << 3;
+ break;
case 128:
center_freq = center_freq << 5; /* q13 */
break;
+ case 120:
+ center_freq = fMult(center_freq, INV480) << 6;
+ break;
case 512:
- center_freq = (fftLine * samplingFreq) << 3; // q13
+ center_freq = (fftLine * samplingFreq) << 3; // q13
break;
case 480:
- center_freq = fMult(center_freq, INV480) << 4; // q13
+ center_freq = fMult(center_freq, INV480) << 4; // q13
break;
default:
center_freq = (FIXP_DBL)0;
}
+
x1 = fMult(center_freq, FOURBY3EM4); /* q13 * q43 - (DFRACT_BITS-1) = q25 */
x2 = fMult(center_freq, PZZZ76)
<< 2; /* q13 * q41 - (DFRACT_BITS-1) + 2 = q25 */
@@ -468,6 +634,14 @@ static void FDKaacEnc_initMinSnr(const LONG bitrate, const LONG samplerate,
qperwin = qperwin - 9;
pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(480.f / 512.f));
break;
+ case 960:
+ pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(960.f/1024.f));
+ qperwin = qperwin - 10;
+ break;
+ case 120:
+ pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(120.f/128.f));
+ qperwin = qperwin - 7;
+ break;
}
/* for short blocks it is assumed that more bits are available */
diff --git a/libAACenc/src/psy_const.h b/libAACenc/src/psy_const.h
index c2d5304..c3f3f64 100644
--- a/libAACenc/src/psy_const.h
+++ b/libAACenc/src/psy_const.h
@@ -108,6 +108,7 @@ amm-info@iis.fraunhofer.de
#define TRANS_FAC 8 /* encoder short long ratio */
+#define FRAME_LEN_LONG_960 (960)
#define FRAME_MAXLEN_SHORT ((1024) / TRANS_FAC)
#define FRAME_LEN_SHORT_128 ((1024) / TRANS_FAC)
#define FRAME_LEN_SHORT_120 (FRAME_LEN_LONG_960 / TRANS_FAC)
diff --git a/libAACenc/src/qc_main.cpp b/libAACenc/src/qc_main.cpp
index ba3bc7e..0bf234c 100644
--- a/libAACenc/src/qc_main.cpp
+++ b/libAACenc/src/qc_main.cpp
@@ -484,6 +484,7 @@ AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate(
{
INT paddingOn;
INT frameLen;
+ //fprintf(stderr, "hQC->padding.paddingRest=%d bytes! (before)\n", hQC->padding.paddingRest);
/* Do we need an extra padding byte? */
paddingOn = FDKaacEnc_framePadding(bitRate, sampleRate, granuleLength,
@@ -1373,6 +1374,8 @@ AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(
qcOut->totFillBits = FDKaacEnc_writeExtensionData(NULL, &fillExtPayload, 0, 0,
syntaxFlags, aot, epConfig);
+ //fprintf(stderr, "FinalizeBitConsumption(): totFillBits=%d, qcOut->totFillBits=%d \n", totFillBits, qcOut->totFillBits);
+
/* now distribute extra fillbits and alignbits */
alignBits =
7 - (qcOut->staticBits + qcOut->usedDynBits + qcOut->elementExtBits +
diff --git a/libFDK/src/FDK_crc.cpp b/libFDK/src/FDK_crc.cpp
index e208338..ecbddb1 100644
--- a/libFDK/src/FDK_crc.cpp
+++ b/libFDK/src/FDK_crc.cpp
@@ -175,10 +175,48 @@ static const USHORT crcLookup_16_12_5_0[256] = {
0x2e93, 0x3eb2, 0x0ed1, 0x1ef0};
/**
+ * \brief This table defines precalculated lookup tables for crc polynom x^16 + x^14 + x^13 + x^12 + x^11 + x^5 + x^3 + x^2 + x^0.
+ */
+static const USHORT crcLookup_16_14_13_12_11_5_3_2_0[256] =
+{
+ 0x0000, 0x782f, 0xf05e, 0x8871, 0x9893, 0xe0bc, 0x68cd, 0x10e2,
+ 0x4909, 0x3126, 0xb957, 0xc178, 0xd19a, 0xa9b5, 0x21c4, 0x59eb,
+ 0x9212, 0xea3d, 0x624c, 0x1a63, 0x0a81, 0x72ae, 0xfadf, 0x82f0,
+ 0xdb1b, 0xa334, 0x2b45, 0x536a, 0x4388, 0x3ba7, 0xb3d6, 0xcbf9,
+ 0x5c0b, 0x2424, 0xac55, 0xd47a, 0xc498, 0xbcb7, 0x34c6, 0x4ce9,
+ 0x1502, 0x6d2d, 0xe55c, 0x9d73, 0x8d91, 0xf5be, 0x7dcf, 0x05e0,
+ 0xce19, 0xb636, 0x3e47, 0x4668, 0x568a, 0x2ea5, 0xa6d4, 0xdefb,
+ 0x8710, 0xff3f, 0x774e, 0x0f61, 0x1f83, 0x67ac, 0xefdd, 0x97f2,
+ 0xb816, 0xc039, 0x4848, 0x3067, 0x2085, 0x58aa, 0xd0db, 0xa8f4,
+ 0xf11f, 0x8930, 0x0141, 0x796e, 0x698c, 0x11a3, 0x99d2, 0xe1fd,
+ 0x2a04, 0x522b, 0xda5a, 0xa275, 0xb297, 0xcab8, 0x42c9, 0x3ae6,
+ 0x630d, 0x1b22, 0x9353, 0xeb7c, 0xfb9e, 0x83b1, 0x0bc0, 0x73ef,
+ 0xe41d, 0x9c32, 0x1443, 0x6c6c, 0x7c8e, 0x04a1, 0x8cd0, 0xf4ff,
+ 0xad14, 0xd53b, 0x5d4a, 0x2565, 0x3587, 0x4da8, 0xc5d9, 0xbdf6,
+ 0x760f, 0x0e20, 0x8651, 0xfe7e, 0xee9c, 0x96b3, 0x1ec2, 0x66ed,
+ 0x3f06, 0x4729, 0xcf58, 0xb777, 0xa795, 0xdfba, 0x57cb, 0x2fe4,
+ 0x0803, 0x702c, 0xf85d, 0x8072, 0x9090, 0xe8bf, 0x60ce, 0x18e1,
+ 0x410a, 0x3925, 0xb154, 0xc97b, 0xd999, 0xa1b6, 0x29c7, 0x51e8,
+ 0x9a11, 0xe23e, 0x6a4f, 0x1260, 0x0282, 0x7aad, 0xf2dc, 0x8af3,
+ 0xd318, 0xab37, 0x2346, 0x5b69, 0x4b8b, 0x33a4, 0xbbd5, 0xc3fa,
+ 0x5408, 0x2c27, 0xa456, 0xdc79, 0xcc9b, 0xb4b4, 0x3cc5, 0x44ea,
+ 0x1d01, 0x652e, 0xed5f, 0x9570, 0x8592, 0xfdbd, 0x75cc, 0x0de3,
+ 0xc61a, 0xbe35, 0x3644, 0x4e6b, 0x5e89, 0x26a6, 0xaed7, 0xd6f8,
+ 0x8f13, 0xf73c, 0x7f4d, 0x0762, 0x1780, 0x6faf, 0xe7de, 0x9ff1,
+ 0xb015, 0xc83a, 0x404b, 0x3864, 0x2886, 0x50a9, 0xd8d8, 0xa0f7,
+ 0xf91c, 0x8133, 0x0942, 0x716d, 0x618f, 0x19a0, 0x91d1, 0xe9fe,
+ 0x2207, 0x5a28, 0xd259, 0xaa76, 0xba94, 0xc2bb, 0x4aca, 0x32e5,
+ 0x6b0e, 0x1321, 0x9b50, 0xe37f, 0xf39d, 0x8bb2, 0x03c3, 0x7bec,
+ 0xec1e, 0x9431, 0x1c40, 0x646f, 0x748d, 0x0ca2, 0x84d3, 0xfcfc,
+ 0xa517, 0xdd38, 0x5549, 0x2d66, 0x3d84, 0x45ab, 0xcdda, 0xb5f5,
+ 0x7e0c, 0x0623, 0x8e52, 0xf67d, 0xe69f, 0x9eb0, 0x16c1, 0x6eee,
+ 0x3705, 0x4f2a, 0xc75b, 0xbf74, 0xaf96, 0xd7b9, 0x5fc8, 0x27e7,
+};
+
+/**
* \brief This table defines precalculated lookup tables for crc polynom x^16
* + x^15 + x^5 + x^0.
*/
-
static const USHORT crcLookup_16_15_5_0[256] = {
0x0000, 0x8021, 0x8063, 0x0042, 0x80e7, 0x00c6, 0x0084, 0x80a5, 0x81ef,
0x01ce, 0x018c, 0x81ad, 0x0108, 0x8129, 0x816b, 0x014a, 0x83ff, 0x03de,
@@ -228,6 +266,10 @@ static void crcCalc(HANDLE_FDK_CRCINFO hCrcInfo, HANDLE_FDK_BITSTREAM hBs,
void FDKcrcInit(HANDLE_FDK_CRCINFO hCrcInfo, const UINT crcPoly,
const UINT crcStartValue, const UINT crcLen) {
/* crc polynom example:
+ DAB+ FireCode:
+ x^16 + x^14 + x^13 + x^12 + x^11 + x^5 + x^3 + x^2 + x^0
+ (1) 0111 1000 0010 1101 -> 0x782d
+
x^16 + x^15 + x^5 + x^0 (1) 1000 0000 0010 0001 -> 0x8021
x^16 + x^15 + x^2 + x^0 (1) 1000 0000 0000 0101 -> 0x8005
x^16 + x^12 + x^5 + x^0 (1) 0001 0000 0010 0001 -> 0x1021
@@ -254,6 +296,9 @@ void FDKcrcInit(HANDLE_FDK_CRCINFO hCrcInfo, const UINT crcPoly,
case 0x1021:
hCrcInfo->pCrcLookup = crcLookup_16_12_5_0;
break;
+ case 0x782d:
+ hCrcInfo->pCrcLookup = crcLookup_16_14_13_12_11_5_3_2_0;
+ break;
case 0x001d:
default:
/* no lookup table */
@@ -406,6 +451,7 @@ static inline INT calcCrc_Bytes(USHORT *const pCrc, const USHORT *pCrcLookup,
}
*pCrc = crc; /* update crc value */
+ //fprintf(stderr, "\n\n crc[%d]=%04x\n", i, crc);
return (nBytes);
}
@@ -475,5 +521,6 @@ static void crcCalc(HANDLE_FDK_CRCINFO hCrcInfo, HANDLE_FDK_BITSTREAM hBs,
}
}
+ //fprintf(stderr, "\n\n crc=%04x\n", crc);
hCrcInfo->crcValue = crc;
}
diff --git a/libFDK/src/FDK_tools_rom.cpp b/libFDK/src/FDK_tools_rom.cpp
index 0095878..e9e1206 100644
--- a/libFDK/src/FDK_tools_rom.cpp
+++ b/libFDK/src/FDK_tools_rom.cpp
@@ -7137,6 +7137,9 @@ const element_list_t *getBitstreamElementList(AUDIO_OBJECT_TYPE aot,
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
+ case AOT_DABPLUS_AAC_LC:
+ case AOT_DABPLUS_SBR:
+ case AOT_DABPLUS_PS:
FDK_ASSERT(epConfig == -1);
if (elFlags & AC_EL_GA_CCE) {
return &node_aac_cce;
diff --git a/libFDK/src/mdct.cpp b/libFDK/src/mdct.cpp
index d697cfb..f5aa284 100644
--- a/libFDK/src/mdct.cpp
+++ b/libFDK/src/mdct.cpp
@@ -285,6 +285,9 @@ void imdct_gain(FIXP_DBL *pGain_m, int *pGain_e, int tl) {
log2_tl = DFRACT_BITS - 1 - fNormz((FIXP_DBL)tl);
gain_e += -log2_tl;
+ FDK_ASSERT(log2_tl - 2 >= 0);
+ FDK_ASSERT(log2_tl - 2 < 8*sizeof(int));
+
/* Detect non-radix 2 transform length and add amplitude compensation factor
which cannot be included into the exponent above */
switch ((tl) >> (log2_tl - 2)) {
diff --git a/libMpegTPEnc/src/tpenc_dab.cpp b/libMpegTPEnc/src/tpenc_dab.cpp
new file mode 100644
index 0000000..202fecf
--- /dev/null
+++ b/libMpegTPEnc/src/tpenc_dab.cpp
@@ -0,0 +1,467 @@
+
+/* -----------------------------------------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+� Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
+ All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
+the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
+This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
+audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
+independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
+of the MPEG specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
+may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
+individually for the purpose of encoding or decoding bit streams in products that are compliant with
+the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
+these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
+software may already be covered under those patent licenses when it is used for those licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
+are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
+applications information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification, are permitted without
+payment of copyright license fees provided that you satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
+your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation and/or other materials
+provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
+You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived from this library without
+prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
+software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
+and the date of any change. For modified versions of the FDK AAC Codec, the term
+"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
+"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
+ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
+respect to this software.
+
+You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
+by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
+"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
+of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
+including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
+or business interruption, however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of this software, even if
+advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------------------------------------- */
+
+/******************************** MPEG Audio Encoder **************************
+
+ Initial author: serge
+ contents/description: DAB Transport Headers support
+
+******************************************************************************/
+#include <stdio.h>
+#include "FDK_audio.h"
+#include "tpenc_dab.h"
+
+
+#include "tpenc_lib.h"
+#include "tpenc_asc.h"
+
+#include "common_fix.h"
+
+int dabWrite_CrcStartReg(
+ HANDLE_DAB pDab, /*!< pointer to dab stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int mBits /*!< number of bits in crc region */
+ )
+{
+ //fprintf(stderr, "dabWrite_CrcStartReg(%p): bits in crc region=%d\n", hBs, mBits);
+ return ( FDKcrcStartReg(&pDab->crcInfo2, hBs, mBits) );
+}
+
+void dabWrite_CrcEndReg(
+ HANDLE_DAB pDab, /*!< pointer to dab crc info stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int reg /*!< crc region */
+ )
+{
+ //fprintf(stderr, "dabWrite_CrcEndReg(%p): crc region=%d\n", hBs, reg);
+ FDKcrcEndReg(&pDab->crcInfo2, hBs, reg);
+}
+
+int dabWrite_GetHeaderBits( HANDLE_DAB hDab )
+{
+ int bits = 0;
+
+ if (hDab->currentBlock == 0) {
+ /* Static and variable header bits */
+ bits += 16; //header_firecode 16
+ bits += 8; //rfa=1, dac_rate=1, sbr_flag=1, aac_channel_mode=1, ps_flag=1, mpeg_surround_config=3
+ bits += 12 * hDab->num_raw_blocks; //au_start[1...num_aus] 12 bit AU start position markers
+
+ //4 byte alignment
+ if (hDab->dac_rate == 0 || hDab->sbr_flag == 0)
+ bits+=4;
+ //16sbr => 16 + 5 + 3 + 12*(2-1) => 36 => 40 bits 5
+ //24sbr => 16 + 5 + 3 + 12*(3-1) => 48 ok 6
+ //32sbr => 16 + 5 + 3 + 12*(4-1) => 60 => 64 bits 8
+ //48sbr => 16 + 5 + 3 + 12*(6-1) => 84 => 88 bits 11
+ }
+
+ /* Add raw data block CRC bits. Not really part of the header, put they cause bit overhead to be accounted. */
+ bits += 16;
+
+
+ return bits;
+}
+
+
+int dabWrite_CountTotalBitDemandHeader( HANDLE_DAB hDab, unsigned int streamDataLength )
+{
+ //fprintf(stderr, "streamDataLength=%d (%d bytes)\n", streamDataLength, streamDataLength >> 3);
+ return dabWrite_GetHeaderBits(hDab);
+}
+
+
+INT dabWrite_Init(HANDLE_DAB hDab, CODER_CONFIG *config)
+{
+ /* Sanity checks */
+ if((int)config->aot > 4
+ || (int)config->aot < 1 ) {
+ return -1;
+ }
+
+ /* Sanity checks DAB-specific */
+ if ( !(config->nSubFrames == 2 && config->samplingRate == 16000 && (config->flags & CC_SBR)) &&
+ !(config->nSubFrames == 3 && config->samplingRate == 24000 && (config->flags & CC_SBR)) &&
+ !(config->nSubFrames == 4 && config->samplingRate == 32000) &&
+ !(config->nSubFrames == 6 && config->samplingRate == 48000)) {
+ return -1;
+ }
+
+ hDab->dac_rate = 0;
+ hDab->aac_channel_mode=0;
+ hDab->sbr_flag = 0;
+ hDab->ps_flag = 0;
+ hDab->mpeg_surround_config=0;
+ hDab->subchannels_num=config->bitRate/8000;
+
+
+ if(config->samplingRate == 24000 || config->samplingRate == 48000)
+ hDab->dac_rate = 1;
+
+ if (config->extAOT==AOT_SBR || config->extAOT == AOT_PS)
+ hDab->sbr_flag = 1;
+
+ if(config->extAOT == AOT_PS)
+ hDab->ps_flag = 1;
+
+
+ if(config->channelMode == MODE_2)
+ hDab->aac_channel_mode = 1;
+
+ //fprintf(stderr, "hDab->dac_rate=%d\n", hDab->dac_rate);
+ //fprintf(stderr, "hDab->sbr_flag=%d\n", hDab->sbr_flag);
+ //fprintf(stderr, "hDab->ps_flag=%d\n", hDab->ps_flag);
+ //fprintf(stderr, "hDab->aac_channel_mode=%d\n", hDab->aac_channel_mode);
+ //fprintf(stderr, "hDab->subchannels_num=%d\n", hDab->subchannels_num);
+ //fprintf(stderr, "cc->nSubFrames=%d\n", config->nSubFrames);
+
+ hDab->num_raw_blocks=config->nSubFrames-1; /* 0 means 1 raw data block */
+
+ FDKcrcInit(&hDab->crcInfo, 0x1021, 0xFFFF, 16);
+ FDKcrcInit(&hDab->crcFire, 0x782d, 0, 16);
+ FDKcrcInit(&hDab->crcInfo2, 0x8005, 0xFFFF, 16);
+
+ hDab->currentBlock = 0;
+ hDab->headerBits = dabWrite_GetHeaderBits(hDab);
+
+ return 0;
+}
+
+int dabWrite_EncodeHeader(HANDLE_DAB hDab,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ int buffer_fullness,
+ int frame_length)
+{
+ INT crcIndex = 0;
+
+
+ FDK_ASSERT(((frame_length+hDab->headerBits)/8)<0x2000); /*13 bit*/
+ FDK_ASSERT(buffer_fullness<0x800); /* 11 bit */
+
+ FDKcrcReset(&hDab->crcInfo);
+
+
+// fprintf(stderr, "dabWrite_EncodeHeader() hDab->currentBlock=%d, frame_length=%d, buffer_fullness=%d\n",
+// hDab->currentBlock, frame_length, buffer_fullness);
+
+// if (hDab->currentBlock == 0) {
+// //hDab->subFrameStartPrev=dabWrite_GetHeaderBits(hDab);
+// fprintf(stderr, "header bits[%d] [%d]\n", hDab->subFrameStartPrev, hDab->subFrameStartPrev >> 3);
+// FDKresetBitbuffer(hBitStream, BS_WRITER);
+// }
+
+ //hDab->subFrameStartBit = FDKgetValidBits(hBitStream);
+// fprintf(stderr, "dabWrite_EncodeHeader() hDab->subFrameStartBit=%d [%d]\n", hDab->subFrameStartBit, hDab->subFrameStartBit >> 3);
+
+ //hDab->subFrameStartBit = FDKgetValidBits(hBitStream);
+ /* Skip new header if this is raw data block 1..n */
+ if (hDab->currentBlock == 0)
+ {
+ FDKresetBitbuffer(hBitStream, BS_WRITER);
+// fprintf(stderr, "dabWrite_EncodeHeader() after FDKresetBitbuffer=%d [%d]\n", FDKgetValidBits(hBitStream), FDKgetValidBits(hBitStream) >> 3);
+
+ /* fixed header */
+ FDKwriteBits(hBitStream, 0, 16); //header_firecode
+ FDKwriteBits(hBitStream, 0, 1); //rfa
+ FDKwriteBits(hBitStream, hDab->dac_rate, 1);
+ FDKwriteBits(hBitStream, hDab->sbr_flag, 1);
+ FDKwriteBits(hBitStream, hDab->aac_channel_mode, 1);
+ FDKwriteBits(hBitStream, hDab->ps_flag, 1);
+ FDKwriteBits(hBitStream, hDab->mpeg_surround_config, 3);
+ /* variable header */
+ int i;
+ for(i=0; i<hDab->num_raw_blocks; i++)
+ FDKwriteBits(hBitStream, 0, 12);
+ /* padding */
+ if (hDab->dac_rate == 0 || hDab->sbr_flag == 0) {
+ FDKwriteBits(hBitStream, 0, 4);
+ }
+ } /* End of DAB header */
+
+ hDab->subFrameStartBit = FDKgetValidBits(hBitStream);
+ FDK_ASSERT(FDKgetValidBits(hBitStream) % 8 == 0); //only aligned header
+
+// fprintf(stderr, "dabWrite_EncodeHeader() FDKgetValidBits(hBitStream)=%d [%d]\n", FDKgetValidBits(hBitStream), FDKgetValidBits(hBitStream) >> 3);
+ return 0;
+}
+
+int dabWrite_writeExtensionFillPayload(HANDLE_FDK_BITSTREAM hBitStream, int extPayloadBits)
+{
+#define EXT_TYPE_BITS ( 4 )
+#define DATA_EL_VERSION_BITS ( 4 )
+#define FILL_NIBBLE_BITS ( 4 )
+
+#define EXT_TYPE_BITS ( 4 )
+#define DATA_EL_VERSION_BITS ( 4 )
+#define FILL_NIBBLE_BITS ( 4 )
+
+ INT extBitsUsed = 0;
+ INT extPayloadType = EXT_FIL;
+ //fprintf(stderr, "FDKaacEnc_writeExtensionPayload() extPayloadType=%d\n", extPayloadType);
+ if (extPayloadBits >= EXT_TYPE_BITS)
+ {
+ UCHAR fillByte = 0x00; /* for EXT_FIL and EXT_FILL_DATA */
+
+ if (hBitStream != NULL) {
+ FDKwriteBits(hBitStream, extPayloadType, EXT_TYPE_BITS);
+ }
+ extBitsUsed += EXT_TYPE_BITS;
+
+ switch (extPayloadType) {
+ case EXT_FILL_DATA:
+ fillByte = 0xA5;
+ case EXT_FIL:
+ default:
+ if (hBitStream != NULL) {
+ int writeBits = extPayloadBits;
+ FDKwriteBits(hBitStream, 0x00, FILL_NIBBLE_BITS);
+ writeBits -= 8; /* acount for the extension type and the fill nibble */
+ while (writeBits >= 8) {
+ FDKwriteBits(hBitStream, fillByte, 8);
+ writeBits -= 8;
+ }
+ }
+ extBitsUsed += FILL_NIBBLE_BITS + (extPayloadBits & ~0x7) - 8;
+ break;
+ }
+ }
+
+ return (extBitsUsed);
+}
+
+void dabWrite_FillRawDataBlock(HANDLE_FDK_BITSTREAM hBitStream, int payloadBits)
+{
+ INT extBitsUsed = 0;
+#define EL_ID_BITS ( 3 )
+#define FILL_EL_COUNT_BITS ( 4 )
+#define FILL_EL_ESC_COUNT_BITS ( 8 )
+#define MAX_FILL_DATA_BYTES ( 269 )
+ while (payloadBits >= (EL_ID_BITS + FILL_EL_COUNT_BITS)) {
+ INT cnt, esc_count=-1, alignBits=7;
+
+ payloadBits -= EL_ID_BITS + FILL_EL_COUNT_BITS;
+ if (payloadBits >= 15*8) {
+ payloadBits -= FILL_EL_ESC_COUNT_BITS;
+ esc_count = 0; /* write esc_count even if cnt becomes smaller 15 */
+ }
+ alignBits = 0;
+
+ cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits+alignBits)>>3);
+
+ if (cnt >= 15) {
+ esc_count = cnt - 15 + 1;
+ }
+
+ if (hBitStream != NULL) {
+ /* write bitstream */
+ FDKwriteBits(hBitStream, ID_FIL, EL_ID_BITS);
+ if (esc_count >= 0) {
+ FDKwriteBits(hBitStream, 15, FILL_EL_COUNT_BITS);
+ FDKwriteBits(hBitStream, esc_count, FILL_EL_ESC_COUNT_BITS);
+ } else {
+ FDKwriteBits(hBitStream, cnt, FILL_EL_COUNT_BITS);
+ }
+ }
+
+ extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS + ((esc_count>=0) ? FILL_EL_ESC_COUNT_BITS : 0);
+
+ cnt = fixMin(cnt*8, payloadBits); /* convert back to bits */
+#if 0
+ extBitsUsed += FDKaacEnc_writeExtensionPayload( hBitStream,
+ pExtension->type,
+ pExtension->pPayload,
+ cnt );
+#else
+ extBitsUsed += dabWrite_writeExtensionFillPayload(hBitStream, cnt);
+#endif
+ payloadBits -= cnt;
+ }
+}
+
+void dabWrite_EndRawDataBlock(HANDLE_DAB hDab,
+ HANDLE_FDK_BITSTREAM hBs,
+ int *pBits)
+{
+ FDK_BITSTREAM bsWriter;
+ INT crcIndex = 0;
+ USHORT crcData;
+ INT writeBits=0;
+ INT writeBitsNonLastBlock=0;
+ INT writeBitsLastBlock=0;
+#if 1
+ if (hDab->currentBlock == hDab->num_raw_blocks) {
+ //calculate byte-alignment before writing ID_FIL
+ if((FDKgetValidBits(hBs)+3) % 8){
+ writeBits = 8 - ((FDKgetValidBits(hBs)+3) % 8);
+ }
+
+ INT offset_end = hDab->subchannels_num*110*8 - 2*8 - 3;
+ writeBitsLastBlock = offset_end - FDKgetValidBits(hBs);
+ dabWrite_FillRawDataBlock(hBs, writeBitsLastBlock);
+ FDKsyncCache(hBs);
+ //fprintf(stderr, "FIL-element written=%d\n", writeBitsLastBlock);
+ writeBitsLastBlock=writeBits;
+ }
+#endif
+ FDKwriteBits(hBs, 7, 3); //finalize AU: ID_END
+ FDKsyncCache(hBs);
+ //byte-align (if ID_FIL doesn't align it).
+ if(FDKgetValidBits(hBs) % 8){
+ writeBits = 8 - (FDKgetValidBits(hBs) % 8);
+ FDKwriteBits(hBs, 0x00, writeBits);
+ FDKsyncCache(hBs);
+ }
+
+ //fake-written bits alignment for last AU
+ if (hDab->currentBlock == hDab->num_raw_blocks)
+ writeBits=writeBitsLastBlock;
+
+ INT frameLen = (FDKgetValidBits(hBs) - hDab->subFrameStartBit) >> 3;
+ //fprintf(stderr, "frame=%d, offset writeBits=%d\n", frameLen, writeBits);
+
+ FDK_ASSERT(FDKgetValidBits(hBs) % 8 == 0); //only aligned au's
+ FDK_ASSERT(hDab->subchannels_num*110*8 >= FDKgetValidBits(hBs)+2*8); //don't overlap superframe
+
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
+ FDKpushFor(&bsWriter, hDab->subFrameStartBit);
+ FDKcrcReset(&hDab->crcInfo);
+ hDab->crcIndex = FDKcrcStartReg(&hDab->crcInfo, &bsWriter, 0);
+#if 0
+ if (hDab->currentBlock == hDab->num_raw_blocks) {
+ INT offset_size = hDab->subchannels_num*110*8 - 2*8 - FDKgetValidBits(hBs);
+ //fprintf(stderr, "offset_size=%d\n", offset_size >> 3);
+ FDKpushFor(hBs, offset_size);
+ }
+#endif
+
+ FDKpushFor(&bsWriter, FDKgetValidBits(hBs) - hDab->subFrameStartBit);
+ FDKcrcEndReg(&hDab->crcInfo, &bsWriter, hDab->crcIndex);
+ crcData = FDKcrcGetCRC(&hDab->crcInfo);
+ //fprintf(stderr, "crcData = %04x\n", crcData);
+ /* Write inverted CRC of current raw data block */
+ FDKwriteBits(hBs, crcData ^ 0xffff, 16);
+ FDKsyncCache(hBs);
+
+
+ /* Write distance to current data block */
+ if(hDab->currentBlock) {
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
+ FDKpushFor(&bsWriter, 24 + (hDab->currentBlock-1)*12);
+ //fprintf(stderr, "FDKwriteBits() = %d\n", hDab->subFrameStartBit>>3);
+ FDKwriteBits(&bsWriter, (hDab->subFrameStartBit>>3), 12);
+ FDKsyncCache(&bsWriter);
+ }
+
+ /* Write FireCode */
+ if (hDab->currentBlock == hDab->num_raw_blocks) {
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
+ FDKpushFor(&bsWriter, 16);
+
+ FDKcrcReset(&hDab->crcFire);
+ crcIndex = FDKcrcStartReg(&hDab->crcFire, &bsWriter, 72);
+ FDKpushFor(&bsWriter, 9*8); //9bytes
+ FDKcrcEndReg(&hDab->crcFire, &bsWriter, crcIndex);
+
+ crcData = FDKcrcGetCRC(&hDab->crcFire);
+ //fprintf(stderr, "Firecode: %04x\n", crcData);
+
+ FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
+ FDKwriteBits(&bsWriter, crcData, 16);
+ FDKsyncCache(&bsWriter);
+ }
+
+ if (hDab->currentBlock == 0)
+ *pBits += hDab->headerBits;
+ else
+ *pBits += 16;
+
+ *pBits += writeBits + 3; //size: ID_END + alignment
+
+ /* Correct *pBits to reflect the amount of bits of the current subframe */
+ *pBits -= hDab->subFrameStartBit;
+ /* Fixup CRC bits, since they come after each raw data block */
+
+ hDab->currentBlock++;
+ //fprintf(stderr, "dabWrite_EndRawDataBlock() *pBits=%d (%d)\n", *pBits, *pBits >> 3);
+}
+
diff --git a/libMpegTPEnc/src/tpenc_dab.h b/libMpegTPEnc/src/tpenc_dab.h
new file mode 100644
index 0000000..17b83c6
--- /dev/null
+++ b/libMpegTPEnc/src/tpenc_dab.h
@@ -0,0 +1,217 @@
+
+/* -----------------------------------------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+� Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
+ All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
+the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
+This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
+audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
+independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
+of the MPEG specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
+may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
+individually for the purpose of encoding or decoding bit streams in products that are compliant with
+the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
+these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
+software may already be covered under those patent licenses when it is used for those licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
+are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
+applications information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification, are permitted without
+payment of copyright license fees provided that you satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
+your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation and/or other materials
+provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
+You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived from this library without
+prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
+software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
+and the date of any change. For modified versions of the FDK AAC Codec, the term
+"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
+"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
+ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
+respect to this software.
+
+You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
+by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
+"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
+of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
+including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
+or business interruption, however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of this software, even if
+advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------------------------------------- */
+
+/******************************** MPEG Audio Encoder **************************
+
+ Initial author: serge
+ contents/description: DAB Transport writer
+
+******************************************************************************/
+
+#ifndef TPENC_DAB_H
+#define TPENC_DAB_H
+
+
+
+#include "tp_data.h"
+
+#include "FDK_crc.h"
+
+typedef struct {
+ USHORT frame_length;
+ UCHAR dac_rate;
+ UCHAR aac_channel_mode;
+ UCHAR sbr_flag;
+ UCHAR ps_flag;
+ UCHAR mpeg_surround_config;
+ UCHAR num_raw_blocks;
+ UCHAR BufferFullnesStartFlag;
+ int subchannels_num;
+ int headerBits; /*!< Header bit demand for the current raw data block */
+ int currentBlock; /*!< Index of current raw data block */
+ int subFrameStartBit; /*!< Bit position where the current raw data block begins */
+ //int subFrameStartPrev; /*!< Bit position where the previous raw data block begins */
+ int crcIndex;
+ FDK_CRCINFO crcInfo;
+ FDK_CRCINFO crcFire;
+ FDK_CRCINFO crcInfo2;
+ USHORT tab[256];
+} STRUCT_DAB;
+
+typedef STRUCT_DAB *HANDLE_DAB;
+
+/**
+ * \brief Initialize DAB data structure
+ *
+ * \param hDab DAB data handle
+ * \param config a valid CODER_CONFIG struct from where the required
+ * information for the DAB header is extrated from
+ *
+ * \return 0 in case of success.
+ */
+INT dabWrite_Init(
+ HANDLE_DAB hDab,
+ CODER_CONFIG *config
+ );
+
+/**
+ * \brief Get the total bit overhead caused by DAB
+ *
+ * \hDab handle to DAB data
+ *
+ * \return Amount of additional bits required for the current raw data block
+ */
+int dabWrite_GetHeaderBits( HANDLE_DAB hDab );
+int dabWrite_CountTotalBitDemandHeader( HANDLE_DAB hDab, unsigned int streamDataLength );
+
+/**
+ * \brief Write an DAB header into the given bitstream. May not write a header
+ * in case of multiple raw data blocks.
+ *
+ * \param hDab DAB data handle
+ * \param hBitStream bitstream handle into which the DAB may be written into
+ * \param buffer_fullness the buffer fullness value for the DAB header
+ * \param the current raw data block length
+ *
+ * \return 0 in case of success.
+ */
+INT dabWrite_EncodeHeader(
+ HANDLE_DAB hDab,
+ HANDLE_FDK_BITSTREAM hBitStream,
+ int bufferFullness,
+ int frame_length
+ );
+/**
+ * \brief Finish a DAB raw data block
+ *
+ * \param hDab DAB data handle
+ * \param hBs bitstream handle into which the DAB may be written into
+ * \param pBits a pointer to a integer holding the current bitstream buffer bit count,
+ * which is corrected to the current raw data block boundary.
+ *
+ */
+void dabWrite_EndRawDataBlock(
+ HANDLE_DAB hDab,
+ HANDLE_FDK_BITSTREAM hBs,
+ int *bits
+ );
+
+
+/**
+ * \brief Start 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 pDab DAB data handle
+ * \param hBs bitstream handle of which the CRC region ends
+ * \param mBits limit of number of bits to be considered for the requested CRC region
+ *
+ * \return ID for the created region, -1 in case of an error
+ */
+int dabWrite_CrcStartReg(
+ HANDLE_DAB pDab,
+ HANDLE_FDK_BITSTREAM hBs,
+ int mBits
+ );
+
+/**
+ * \brief Ends CRC region identified by reg
+ *
+ * \param pDab DAB data handle
+ * \param hBs bitstream handle of which the CRC region ends
+ * \param reg a CRC region ID returned previously by dabWrite_CrcStartReg()
+ */
+void dabWrite_CrcEndReg(
+ HANDLE_DAB pDab,
+ HANDLE_FDK_BITSTREAM hBs,
+ int reg
+ );
+
+
+
+
+#endif /* TPENC_DAB_H */
+
diff --git a/libMpegTPEnc/src/tpenc_lib.cpp b/libMpegTPEnc/src/tpenc_lib.cpp
index 14ea5fe..316c6e0 100644
--- a/libMpegTPEnc/src/tpenc_lib.cpp
+++ b/libMpegTPEnc/src/tpenc_lib.cpp
@@ -113,6 +113,8 @@ amm-info@iis.fraunhofer.de
#include "tpenc_adif.h"
+#include "tpenc_dab.h"
+
#include "tpenc_latm.h"
typedef struct {
@@ -137,6 +139,8 @@ struct TRANSPORTENC {
ADIF_INFO adif;
+ STRUCT_DAB dab;
+
LATM_STREAM latm;
RAWPACKETS_INFO raw;
@@ -215,6 +219,7 @@ static INT getPceRepetitionRate(const CHANNEL_MODE channelMode,
FDK_FALLTHROUGH;
case TT_MP4_LOAS: /* PCE in ASC if chChonfig==0 */
case TT_MP4_LATM_MCP1: /* PCE in ASC if chChonfig==0 */
+ case TT_DABPLUS:
default:
pceFrameCounter = -1; /* no PCE in raw_data_block */
}
@@ -233,6 +238,7 @@ static INT getPceRepetitionRate(const CHANNEL_MODE channelMode,
case TT_MP4_RAW:
pceFrameCounter = headerPeriod;
break;
+ case TT_DABPLUS:
default:
pceFrameCounter = -1; /* no PCE in raw_data_block */
} /* switch transportFmt */
@@ -295,6 +301,18 @@ TRANSPORTENC_ERROR transportEnc_Init(HANDLE_TRANSPORTENC hTpEnc,
}
break;
+ case TT_DABPLUS:
+ /* Sanity checks */
+ if ( ( hTpEnc->config.aot != AOT_AAC_LC)
+ ||(hTpEnc->config.samplesPerFrame != 960) )
+ {
+ return TRANSPORTENC_INVALID_PARAMETER;
+ }
+ if ( dabWrite_Init(&hTpEnc->writer.dab, &hTpEnc->config) != 0) {
+ return TRANSPORTENC_INVALID_PARAMETER;
+ }
+ break;
+
case TT_MP4_LOAS:
case TT_MP4_LATM_MCP0:
case TT_MP4_LATM_MCP1: {
@@ -410,6 +428,17 @@ TRANSPORTENC_ERROR transportEnc_WriteAccessUnit(HANDLE_TRANSPORTENC hTp,
adtsWrite_EncodeHeader(&hTp->writer.adts, &hTp->bitStream, bufferFullness,
frameUsedBits);
break;
+ case TT_DABPLUS:
+ bufferFullness /= ncc; /* Number of Considered Channels */
+ bufferFullness /= 32;
+ bufferFullness = FDKmin(0x7FF, bufferFullness); /* Signal variable rate */
+ dabWrite_EncodeHeader(
+ &hTp->writer.dab,
+ &hTp->bitStream,
+ bufferFullness,
+ frameUsedBits
+ );
+ break;
case TT_MP4_LOAS:
case TT_MP4_LATM_MCP0:
case TT_MP4_LATM_MCP1:
@@ -478,6 +507,9 @@ TRANSPORTENC_ERROR transportEnc_EndAccessUnit(HANDLE_TRANSPORTENC hTp,
case TT_MP4_ADTS:
adtsWrite_EndRawDataBlock(&hTp->writer.adts, &hTp->bitStream, bits);
break;
+ case TT_DABPLUS:
+ dabWrite_EndRawDataBlock(&hTp->writer.dab, &hTp->bitStream, bits);
+ break;
case TT_MP4_ADIF:
/* Substract ADIF header from AU bits, not to be considered. */
*bits -= adifWrite_GetHeaderBits(&hTp->writer.adif);
@@ -514,6 +546,14 @@ TRANSPORTENC_ERROR transportEnc_GetFrame(HANDLE_TRANSPORTENC hTpEnc,
*nbytes = 0;
}
break;
+ case TT_DABPLUS:
+ if (hTpEnc->writer.dab.currentBlock >= hTpEnc->writer.dab.num_raw_blocks+1) {
+ *nbytes = (FDKgetValidBits(hBs) + 7)>>3;
+ hTpEnc->writer.dab.currentBlock = 0;
+ } else {
+ *nbytes = 0;
+ }
+ break;
case TT_MP4_ADIF:
FDK_ASSERT((INT)FDKgetValidBits(hBs) >= 0);
*nbytes = (FDKgetValidBits(hBs) + 7) >> 3;
@@ -551,6 +591,9 @@ INT transportEnc_GetStaticBits(HANDLE_TRANSPORTENC hTp, int auBits) {
case TT_MP4_ADTS:
nbits = adtsWrite_GetHeaderBits(&hTp->writer.adts);
break;
+ case TT_DABPLUS:
+ nbits = dabWrite_CountTotalBitDemandHeader(&hTp->writer.dab, auBits);
+ break;
case TT_MP4_LOAS:
case TT_MP4_LATM_MCP0:
case TT_MP4_LATM_MCP1:
@@ -585,6 +628,9 @@ int transportEnc_CrcStartReg(HANDLE_TRANSPORTENC hTpEnc, int mBits) {
crcReg = adtsWrite_CrcStartReg(&hTpEnc->writer.adts, &hTpEnc->bitStream,
mBits);
break;
+ case TT_DABPLUS:
+ crcReg = dabWrite_CrcStartReg(&hTpEnc->writer.dab, &hTpEnc->bitStream, mBits);
+ break;
default:
break;
}
@@ -597,6 +643,9 @@ void transportEnc_CrcEndReg(HANDLE_TRANSPORTENC hTpEnc, int reg) {
case TT_MP4_ADTS:
adtsWrite_CrcEndReg(&hTpEnc->writer.adts, &hTpEnc->bitStream, reg);
break;
+ case TT_DABPLUS:
+ dabWrite_CrcEndReg(&hTpEnc->writer.dab, &hTpEnc->bitStream, reg);
+ break;
default:
break;
}
@@ -658,7 +707,7 @@ TRANSPORTENC_ERROR transportEnc_GetLibInfo(LIB_INFO *info) {
/* Set flags */
info->flags =
- 0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS | CAPF_RAWPACKETS;
+ 0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS | CAPF_RAWPACKETS | CAPF_DAB_AAC;
return TRANSPORTENC_OK;
}
diff --git a/libSBRenc/src/env_est.cpp b/libSBRenc/src/env_est.cpp
index 0eb8425..4af561b 100644
--- a/libSBRenc/src/env_est.cpp
+++ b/libSBRenc/src/env_est.cpp
@@ -1151,6 +1151,7 @@ void FDKsbrEnc_extractSbrEnvelope2(
SBR_STEREO_MODE stereoMode = h_con->stereoMode;
int nChannels = h_con->nChannels;
+ FDK_ASSERT(nChannels <= MAX_NUM_CHANNELS);
const int *v_tuning;
static const int v_tuningHEAAC[6] = {0, 2, 4, 0, 0, 0};
diff --git a/libSBRenc/src/sbr_encoder.cpp b/libSBRenc/src/sbr_encoder.cpp
index df9e996..26257a1 100644
--- a/libSBRenc/src/sbr_encoder.cpp
+++ b/libSBRenc/src/sbr_encoder.cpp
@@ -2096,7 +2096,7 @@ INT sbrEncoder_Init(HANDLE_SBR_ENCODER hSbrEncoder,
*downSampleFactor = 2;
}
- if (aot == AOT_PS) {
+ if (aot == AOT_PS || aot == AOT_DABPLUS_PS) {
usePs = 1;
}
if (aot == AOT_ER_AAC_ELD) {
diff --git a/libSYS/include/FDK_audio.h b/libSYS/include/FDK_audio.h
index 0e440c9..d69c008 100644
--- a/libSYS/include/FDK_audio.h
+++ b/libSYS/include/FDK_audio.h
@@ -145,7 +145,8 @@ typedef enum {
TT_MP4_LOAS = 10, /**< Audio Sync Stream. */
- TT_DRM = 12 /**< Digital Radio Mondial (DRM30/DRM+) bitstream format. */
+ TT_DRM = 12, /**< Digital Radio Mondial (DRM30/DRM+) bitstream format. */
+ TT_DABPLUS = 13 /**< Digital Audio Broadcastong (DAB+) superframes bitstream format. */
} TRANSPORT_TYPE;
@@ -205,6 +206,11 @@ typedef enum {
AOT_SAOC = 43, /**< SAOC */
AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */
+ 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 */
+
+
/* Pseudo AOTs */
AOT_MP2_AAC_LC = 129, /**< Virtual AOT MP2 Low Complexity profile */
AOT_MP2_SBR = 132, /**< Virtual AOT MP2 Low Complexity Profile with SBR */
@@ -626,6 +632,14 @@ typedef enum {
#define CAPF_SBR_HBEHQ \
0x00000100 /**< Support flag for HQ HBE */
+/* DAB capability flags */
+#define CAPF_DAB_MP2 0x00000001 /**< Support flag for Layer2 DAB. */
+#define CAPF_DAB_AAC 0x00000002 /**< Support flag for DAB+ (HE-AAC v2). */
+#define CAPF_DAB_PAD 0x00000004 /**< Support flag for PAD extraction. */
+#define CAPF_DAB_DRC 0x00000008 /**< Support flag for Dynamic Range Control. */
+#define CAPF_DAB_SURROUND 0x00000010 /**< Support flag for DAB Surround (MPS). */
+
+
/* PCM utils capability flags */
#define CAPF_DMX_BLIND \
0x00000001 /**< Support flag for blind downmixing. */