aboutsummaryrefslogtreecommitdiffstats
path: root/libAACenc/src
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2013-12-14 17:32:17 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2018-09-12 14:20:53 +0200
commitbdfafd471e3c7c240b5c78e8d1233ce61f17c296 (patch)
tree4cff9d116268d3941bd328e606c15f0ee8d3a6df /libAACenc/src
parent651ff34d8d35fb6a3b75471d54b271852f5924cc (diff)
downloadfdk-aac-bdfafd471e3c7c240b5c78e8d1233ce61f17c296.tar.gz
fdk-aac-bdfafd471e3c7c240b5c78e8d1233ce61f17c296.tar.bz2
fdk-aac-bdfafd471e3c7c240b5c78e8d1233ce61f17c296.zip
Add DAB+ support
Diffstat (limited to 'libAACenc/src')
-rw-r--r--libAACenc/src/aacenc.cpp32
-rw-r--r--libAACenc/src/aacenc_lib.cpp106
-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
8 files changed, 369 insertions, 30 deletions
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 2f34d4d..220830a 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;
}
@@ -919,6 +949,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;
@@ -1143,7 +1188,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. */
{
@@ -2061,7 +2122,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 */
@@ -2086,18 +2147,21 @@ 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;
}
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;
}
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))) {
@@ -2129,6 +2193,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;
@@ -2215,6 +2281,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:
@@ -2257,17 +2324,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;
}
@@ -2317,7 +2385,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 652d1fd..18dfe95 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"
@@ -1195,6 +1196,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];
@@ -1281,20 +1299,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);
}
@@ -1312,9 +1350,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 +