diff options
Diffstat (limited to 'libAACenc/src')
-rw-r--r-- | libAACenc/src/aacenc.cpp | 32 | ||||
-rw-r--r-- | libAACenc/src/aacenc_lib.cpp | 106 | ||||
-rw-r--r-- | libAACenc/src/aacenc_tns.cpp | 19 | ||||
-rw-r--r-- | libAACenc/src/bitenc.cpp | 56 | ||||
-rw-r--r-- | libAACenc/src/dyn_bits.cpp | 2 | ||||
-rw-r--r-- | libAACenc/src/psy_configuration.cpp | 180 | ||||
-rw-r--r-- | libAACenc/src/psy_const.h | 1 | ||||
-rw-r--r-- | libAACenc/src/qc_main.cpp | 3 |
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 + |