diff options
| -rw-r--r-- | Makefile.am | 3 | ||||
| -rw-r--r-- | README.md | 9 | ||||
| -rwxr-xr-x | bootstrap | 4 | ||||
| -rw-r--r-- | libAACenc/include/aacenc_lib.h | 6 | ||||
| -rw-r--r-- | libAACenc/src/aacenc.cpp | 44 | ||||
| -rw-r--r-- | libAACenc/src/aacenc_lib.cpp | 103 | ||||
| -rw-r--r-- | libAACenc/src/aacenc_tns.cpp | 21 | ||||
| -rw-r--r-- | libAACenc/src/bandwidth.cpp | 2 | ||||
| -rw-r--r-- | libAACenc/src/bitenc.cpp | 64 | ||||
| -rw-r--r-- | libAACenc/src/dyn_bits.cpp | 2 | ||||
| -rw-r--r-- | libAACenc/src/psy_configuration.cpp | 174 | ||||
| -rw-r--r-- | libAACenc/src/psy_const.h | 1 | ||||
| -rw-r--r-- | libAACenc/src/psy_main.cpp | 2 | ||||
| -rw-r--r-- | libAACenc/src/qc_main.cpp | 14 | ||||
| -rw-r--r-- | libFDK/src/FDK_crc.cpp | 94 | ||||
| -rw-r--r-- | libFDK/src/FDK_tools_rom.cpp | 3 | ||||
| -rw-r--r-- | libFDK/src/fft.cpp | 9 | ||||
| -rw-r--r-- | libFDK/src/mdct.cpp | 3 | ||||
| -rw-r--r-- | libMpegTPEnc/src/tpenc_dab.cpp | 467 | ||||
| -rw-r--r-- | libMpegTPEnc/src/tpenc_dab.h | 217 | ||||
| -rw-r--r-- | libMpegTPEnc/src/tpenc_lib.cpp | 52 | ||||
| -rw-r--r-- | libSBRenc/src/env_est.cpp | 1 | ||||
| -rw-r--r-- | libSBRenc/src/sbr_encoder.cpp | 2 | ||||
| -rw-r--r-- | libSYS/include/FDK_audio.h | 14 | 
24 files changed, 1262 insertions, 49 deletions
| diff --git a/Makefile.am b/Makefile.am index 1ee2dfc..9ead8f1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -127,7 +127,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..308f292 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +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. + +See www.opendigitalradio.org for more 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 63c3697..de60a7a 100644 --- a/libAACenc/include/aacenc_lib.h +++ b/libAACenc/include/aacenc_lib.h @@ -90,7 +90,7 @@ amm-info@iis.fraunhofer.de   * \file   aacenc_lib.h   * \brief  FDK AAC Encoder library interface header file.   * -\mainpage  Introduction +\page  FDK AAC Encoder Library Introduction  \section Scope @@ -923,6 +923,7 @@ typedef enum    AACENC_GRANULE_LENGTH           = 0x0105,  /*!< Core encoder (AAC) audio frame length in samples:                                                    - 1024: Default configuration. +                                                  - 960: DRM/DAB+.                                                    - 512: Default LD/ELD configuration.                                                    - 480: Optional length in LD/ELD configuration. */ @@ -1028,8 +1029,9 @@ typedef enum                                                     For AAC-ELD, the SBR information is transmitted in the ELDSpecific Config, which is part of the                                                     AudioSpecificConfig. Therefore, the settings here will have no effect on AAC-ELD.*/ -  AACENC_TPSUBFRAMES              = 0x0303,  /*!< Number of sub frames in a transport frame for LOAS/LATM or ADTS (default 1). +  AACENC_TPSUBFRAMES              = 0x0303,  /*!< Number of sub frames in a transport frame for LOAS/LATM, DAB+ 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              = 0x0304,  /*!< AudioMuxVersion to be used for LATM. (AudioMuxVersionA, currently not implemented): diff --git a/libAACenc/src/aacenc.cpp b/libAACenc/src/aacenc.cpp index 5e8c08d..d7b06d0 100644 --- a/libAACenc/src/aacenc.cpp +++ b/libAACenc/src/aacenc.cpp @@ -87,7 +87,7 @@ amm-info@iis.fraunhofer.de     contents/description: fast aac coder functions  ******************************************************************************/ - +#include <stdio.h>  #include "aacenc.h"  #include "bitenc.h" @@ -170,6 +170,7 @@ INT FDKaacEnc_LimitBitrate(    do {      prevBitRate = bitRate;       averageBitsPerFrame = (bitRate*(frameLength>>shift)) / (coreSamplingRate>>shift) / nSubFrames; +     //fprintf(stderr, "FDKaacEnc_LimitBitrate(): averageBitsPerFrame=%d, prevBitRate=%d, nSubFrames=%d\n", averageBitsPerFrame, prevBitRate, bitRate);      if (pAverageBitsPerFrame != NULL) {        *pAverageBitsPerFrame = averageBitsPerFrame; @@ -182,14 +183,18 @@ INT FDKaacEnc_LimitBitrate(        transportBits = 208;      } +    //fprintf(stderr, "FDKaacEnc_LimitBitrate(): transportBits=%d, FDKmax(%d, %d)\n", transportBits, bitRate, +    //        ((((40 * nChannels) + transportBits) * (coreSamplingRate)) / frameLength));      bitRate = FDKmax(bitRate, ((((40 * nChannels) + transportBits) * (coreSamplingRate)) / frameLength) );      FDK_ASSERT(bitRate >= 0); +    //fprintf(stderr, "FDKaacEnc_LimitBitrate(): FDKmin(%d, %d)\n", bitRate, ((nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN)*(coreSamplingRate>>shift)) / (frameLength>>shift));      bitRate = FDKmin(bitRate, ((nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN)*(coreSamplingRate>>shift)) / (frameLength>>shift)) ;      FDK_ASSERT(bitRate >= 0);    } while (prevBitRate != bitRate && iter++ < 3) ; +  //fprintf(stderr, "FDKaacEnc_LimitBitrate(): bitRate=%d\n", bitRate);    return bitRate;  } @@ -458,6 +463,36 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC      hAacEnc,        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( @@ -489,6 +524,7 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC      hAacEnc,    switch (config->framelength)    {      case 1024: +    case 960: //TODO: DRM        if ( config->audioObjectType == AOT_ER_AAC_LD          || config->audioObjectType == AOT_ER_AAC_ELD )        { @@ -611,6 +647,7 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC      hAacEnc,        qcInit.averageBits     = (averageBitsPerFrame+7)&~7;        maxBitres              = (MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff) - qcInit.averageBits;        qcInit.bitRes          = (config->bitreservoir!=-1) ? FDKmin(config->bitreservoir, maxBitres) : maxBitres; +      //fprintf(stderr, "qcInit.bitRes=%d\n", qcInit.bitRes);        qcInit.maxBits         = fixMin(MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes);        qcInit.maxBits         = (config->maxBitsPerFrame!=-1) ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) : qcInit.maxBits; @@ -736,6 +773,7 @@ AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC       hAacEnc,      /* advance psychoacoustics */      for (el=0; el<cm->nElements; el++) {          ELEMENT_INFO elInfo = cm->elInfo[el]; +        //fprintf(stderr, "elInfo.elType=%d\n", elInfo.elType);          if ( (elInfo.elType == ID_SCE)            || (elInfo.elType == ID_CPE) @@ -896,10 +934,13 @@ AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC       hAacEnc,              /* adjust super frame bitrate */              avgTotalBits *= hAacEnc->config->nSubFrames; +            //fprintf(stderr, "avgTotalBits=%d x %d\n", avgTotalBits, hAacEnc->config->nSubFrames);          }          /* Make first estimate of transport header overhead.             Take maximum possible frame size into account to prevent bitreservoir underrun. */ + +        //fprintf(stderr, "avgTotalBits=%d, bitResTot=%d\n", avgTotalBits, hAacEnc->qcKernel->bitResTot);          hAacEnc->qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, avgTotalBits + hAacEnc->qcKernel->bitResTot); @@ -951,6 +992,7 @@ AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC       hAacEnc,          /*-------------------------------------------- */          /* for ( all sub frames ) ... */ +        //fprintf(stderr, "totalBits=%d, qcOut->totalBits=%d, qcOut->totFillBits=%d\n", totalBits, qcOut->totalBits, qcOut->totFillBits);                /* write bitstream header */                transportEnc_WriteAccessUnit(                      hTpEnc, diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp index fc58d6d..1ea9a5c 100644 --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_lib.cpp @@ -87,7 +87,7 @@ amm-info@iis.fraunhofer.de    contents/description: FDK HE-AAC Encoder interface library functions  ****************************************************************************/ - +#include <stdio.h>  #include "aacenc_lib.h"  #include "FDK_audio.h"  #include "aacenc.h" @@ -327,7 +327,8 @@ static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig)  {      INT sbrUsed = 0; -    if ( (hAacConfig->audioObjectType==AOT_SBR) || (hAacConfig->audioObjectType==AOT_PS) ) +    if ( (hAacConfig->audioObjectType==AOT_SBR) || (hAacConfig->audioObjectType==AOT_PS) +      || (hAacConfig->audioObjectType==AOT_DABPLUS_SBR) || (hAacConfig->audioObjectType==AOT_DABPLUS_PS) )      {          sbrUsed = 1;      } @@ -343,7 +344,8 @@ static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType)  {      INT psUsed = 0; -    if ( (audioObjectType==AOT_PS) ) +    if ( (audioObjectType==AOT_PS) +      || (audioObjectType==AOT_DABPLUS_PS) )      {          psUsed = 1;      } @@ -368,7 +370,8 @@ static SBR_PS_SIGNALING getSbrSignalingMode(      sbrSignaling = SIG_IMPLICIT; /* default: implicit signaling */    } -  if ( (audioObjectType==AOT_AAC_LC) || (audioObjectType==AOT_SBR) || (audioObjectType==AOT_PS) ) { +  if ((audioObjectType==AOT_AAC_LC)     || (audioObjectType==AOT_SBR)     || (audioObjectType==AOT_PS)    || +      (audioObjectType==AOT_DABPLUS_SBR) || (audioObjectType==AOT_DABPLUS_PS) ) {      switch (transportType) {        case TT_MP4_ADIF:        case TT_MP4_ADTS: @@ -424,7 +427,22 @@ static void FDKaacEnc_MapConfig(    cc->flags = 0; -  transport_AOT = hAacConfig->audioObjectType; +  /* Map virtual aot to transport aot. */ +  switch (hAacConfig->audioObjectType) { +    case AOT_DABPLUS_AAC_LC: +      transport_AOT = AOT_AAC_LC; +      break; +    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; +  }    if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) {      cc->flags |= (hAacConfig->syntaxFlags & AC_SBR_PRESENT) ? CC_SBR : 0; @@ -465,9 +483,27 @@ static void FDKaacEnc_MapConfig(    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; @@ -724,6 +760,7 @@ INT aacEncoder_LimitBitrate(    FDK_ASSERT(bitRate > 0); +  //fprintf(stderr, "aacEncoder_LimitBitrate(): bitRate=%d\n", bitRate);    return bitRate;  } @@ -734,7 +771,7 @@ INT aacEncoder_LimitBitrate(   *   * \hAacEncoder Internal encoder config which is to be updated   * \param config User provided config (public struct) - * \return ´returns always AAC_ENC_OK + * \return �returns always AAC_ENC_OK   */  static  AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, @@ -777,10 +814,36 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,        case AOT_PS:            config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_MP4_ADTS;            hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 1024; -          if (hAacConfig->framelength != 1024) { +          if (hAacConfig->framelength != 1024 && hAacConfig->framelength != 960) {              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; +#if 0 +      case AOT_ER_AAC_LC: +          hAacConfig->epConfig = 0; +          hAacConfig->syntaxFlags |= AC_ER; +          hAacConfig->syntaxFlags |= ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0); +          hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0); +          config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS; +          hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 1024; +          if (hAacConfig->framelength != 1024 && hAacConfig->framelength != 960) { +            return AACENC_INVALID_CONFIG; +          } +          break; +#endif        case AOT_ER_AAC_LD:            hAacConfig->epConfig = 0;            hAacConfig->syntaxFlags |= AC_ER|AC_LD; @@ -810,6 +873,7 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,            break;      } +      switch ( hAacConfig->audioObjectType ) {        case AOT_ER_AAC_LD:        case AOT_ER_AAC_ELD: @@ -927,6 +991,7 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, +    //fprintf(stderr, "config->userBitrate=%d\n", config->userBitrate);      /* We need the frame length to call aacEncoder_LimitBitrate() */      hAacConfig->bitRate = aacEncoder_LimitBitrate(                NULL, @@ -940,6 +1005,7 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,                hAacConfig->sbrRatio,                hAacConfig->audioObjectType                ); +    //fprintf(stderr, "hAacConfig->bitRate=%d\n", hAacConfig->bitRate);      /* Configure PNS */      if ( ((hAacConfig->bitrateMode>=1) && (hAacConfig->bitrateMode<=5)) /* VBR without PNS. */ @@ -984,6 +1050,7 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,          hAacEncoder->metaDataAllowed = 0;      } +    //fprintf(stderr, "hAacEncoder->metaDataAllowed=%d\n", hAacEncoder->metaDataAllowed);      return err;  } @@ -1294,8 +1361,10 @@ AACENC_ERROR aacEncOpen(      }      { /* Get bitstream outputbuffer size */ +      UINT buffer_bytes_min = (hAacEncoder->nMaxSubFrames*hAacEncoder->nMaxAacChannels*6144)>>3; +      buffer_bytes_min = fixMax(buffer_bytes_min, (UINT) (24 * 110));   // consider maximum DAB+ Superframe size        UINT ld_M; -      for (ld_M=1; (UINT)(1<<ld_M) < (hAacEncoder->nMaxSubFrames*hAacEncoder->nMaxAacChannels*6144)>>3; ld_M++) ; +      for (ld_M=1; (UINT)(1<<ld_M) < buffer_bytes_min; ld_M++) ;        hAacEncoder->outBufferInBytes = (1<<ld_M);  /* buffer has to be 2^n */      }      hAacEncoder->outBuffer = GetRam_bsOutbuffer(); @@ -1744,6 +1813,7 @@ AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info)    /* Capability flags */    info[i].flags = 0      | CAPF_AAC_1024 | CAPF_AAC_LC +    | CAPF_AAC_960      | CAPF_AAC_512      | CAPF_AAC_480      | CAPF_AAC_DRC @@ -1776,16 +1846,20 @@ AACENC_ERROR aacEncoder_SetParam(              /* check if AOT matches the allocated modules */              switch ( value ) {                case AOT_PS: +              case AOT_DRM_SBR: // Added mfeilen +              case AOT_DABPLUS_PS:                  if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) {                    err = AACENC_INVALID_CONFIG;                    goto bail;                  }                case AOT_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_DABPLUS_AAC_LC:                case AOT_ER_AAC_LD:                case AOT_ER_AAC_ELD:                  if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) { @@ -1811,7 +1885,12 @@ AACENC_ERROR aacEncoder_SetParam(          if (settings->userBitrateMode != value) {              switch ( value ) {                case 0: -              case 1: case 2: case 3: case 4: case 5: +              case 1: +              case 2: +              case 3: +              case 4: +              case 5: +              case 7:                case 8:                  settings->userBitrateMode = value;                  hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; @@ -1888,6 +1967,7 @@ AACENC_ERROR aacEncoder_SetParam(          if (settings->userFramelength != value) {            switch (value) {              case 1024: +            case 960:              case 512:              case 480:                settings->userFramelength = value; @@ -1927,6 +2007,7 @@ AACENC_ERROR aacEncoder_SetParam(                   || ((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; @@ -1974,7 +2055,7 @@ AACENC_ERROR aacEncoder_SetParam(          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 3026d69..f036518 100644 --- a/libAACenc/src/aacenc_tns.cpp +++ b/libAACenc/src/aacenc_tns.cpp @@ -166,6 +166,22 @@ static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab1024[] =    { 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 tnsMaxBandsTab480[] =  {    { 48000, { 31, -1}}, @@ -261,6 +277,10 @@ static INT getTnsMaxBands(    int maxBandsTabSize = 0;    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); @@ -386,6 +406,7 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate,    tC->lpcStopLine    = pC->sfbOffset[tC->lpcStopBand];    switch (granuleLength) { +    case 960:      case 1024:        /* TNS start line: skip lower MDCT lines to prevent artifacts due to filter mismatch */        tC->lpcStartBand[LOFILT]   = (blockType == SHORT_WINDOW) ? 0 : ((sampleRate <= 8000) ? 2 : ((sampleRate < 18783) ? 4 : 8)); diff --git a/libAACenc/src/bandwidth.cpp b/libAACenc/src/bandwidth.cpp index 6937362..af2a2cf 100644 --- a/libAACenc/src/bandwidth.cpp +++ b/libAACenc/src/bandwidth.cpp @@ -204,6 +204,7 @@ static INT GetBandwidthEntry(    INT bwTabSize = 0;    switch (frameLength) { +    case 960:      case 1024:        pBwTab = bandWidthTable;        bwTabSize = sizeof(bandWidthTable)/sizeof(BANDWIDTH_TAB); @@ -252,6 +253,7 @@ static INT GetBandwidthEntry(            chanBitRate < pBwTab[i+1].chanBitRate)        {          switch (frameLength) { +          case 960:            case 1024:              bandwidth = (entryNo==0)                ? pBwTab[i].bandWidthMono diff --git a/libAACenc/src/bitenc.cpp b/libAACenc/src/bitenc.cpp index 8e477aa..4552457 100644 --- a/libAACenc/src/bitenc.cpp +++ b/libAACenc/src/bitenc.cpp @@ -87,7 +87,7 @@ amm-info@iis.fraunhofer.de     contents/description: Bitstream encoder  ******************************************************************************/ - +#include <stdio.h>  #include "bitenc.h"  #include "bit_cnt.h"  #include "dyn_bits.h" @@ -645,7 +645,7 @@ static INT FDKaacEnc_writeExtensionPayload( HANDLE_FDK_BITSTREAM  hBitStream,    #define FILL_NIBBLE_BITS      ( 4 )    INT  extBitsUsed = 0; - +  //fprintf(stderr, "FDKaacEnc_writeExtensionPayload() extPayloadType=%d\n", extPayloadType);    if (extPayloadBits >= EXT_TYPE_BITS)    {      UCHAR  fillByte = 0x00;  /* for EXT_FIL and EXT_FILL_DATA */ @@ -749,7 +749,7 @@ static INT FDKaacEnc_writeDataStreamElement( HANDLE_TRANSPORTENC  hTpEnc,    #define MAX_DSE_DATA_BYTES        ( 510 )    INT  dseBitsUsed = 0; - +  //fprintf(stderr, "FDKaacEnc_writeDataStreamElement() dataPayloadBytes=%d\n", dataPayloadBytes);    while (dataPayloadBytes > 0)    {      int esc_count = -1; @@ -840,6 +840,7 @@ INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC  hTpEnc,      hBitStream = transportEnc_GetBitstream(hTpEnc);    } +  //fprintf(stderr, "FDKaacEnc_writeExtensionData() pExtension->type=%d\n", pExtension->type);    if (syntaxFlags & (AC_SCALABLE|AC_ER))    {      if ( syntaxFlags & AC_DRM ) @@ -1196,6 +1197,7 @@ AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( HANDLE_TRANSPORTENC  hTpEnc,      case esc1_hcr: +      //TODO: DRM!        if (syntaxFlags & AC_ER_HCR)        {          error = AAC_ENC_UNKNOWN; @@ -1301,6 +1303,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++) { @@ -1392,7 +1411,7 @@ AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,          if (channelElementExtensionWritten[i][n]==0)          { -          /* Write all ramaining extension payloads in element */ +          /* Write all remaining extension payloads in element */            FDKaacEnc_writeExtensionData( hTpEnc,                                         &qcOut->qcElement[i]->extension[n],                                          0, @@ -1429,25 +1448,38 @@ AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,    /* Add fill data / stuffing bits */    n = qcOut->nExtensions; -  qcOut->extension[n].type = EXT_FILL_DATA; -  qcOut->extension[n].nPayloadBits = qcOut->totFillBits; -  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 ); +      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);    } @@ -1466,9 +1498,11 @@ AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,    transportEnc_EndAccessUnit(hTpEnc, &frameBits);    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 0c07109..3105fb4 100644 --- a/libAACenc/src/dyn_bits.cpp +++ b/libAACenc/src/dyn_bits.cpp @@ -416,6 +416,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 9a72c68..45b7d13 100644 --- a/libAACenc/src/psy_configuration.cpp +++ b/libAACenc/src/psy_configuration.cpp @@ -119,6 +119,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, @@ -220,10 +375,13 @@ static AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(LONG sampleRate, INT blockType,    */    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); @@ -307,9 +465,15 @@ static FIXP_DBL FDKaacEnc_BarcLineValue(INT noOfLines, INT fftLine, LONG samplin        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          break; @@ -505,6 +669,14 @@ static void FDKaacEnc_initMinSnr(const LONG   bitrate,          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 d9c9f43..15a69c9 100644 --- a/libAACenc/src/psy_const.h +++ b/libAACenc/src/psy_const.h @@ -96,6 +96,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) diff --git a/libAACenc/src/psy_main.cpp b/libAACenc/src/psy_main.cpp index 446c894..eeb0fa2 100644 --- a/libAACenc/src/psy_main.cpp +++ b/libAACenc/src/psy_main.cpp @@ -818,7 +818,7 @@ AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT                 channels,                        &hThisPsyConf[1]->tnsConf);              } -            FDK_ASSERT(1==commonWindow); /* all checks for TNS do only work for common windows (which is always set)*/ +            FDK_ASSERT(commonWindow==1); /* all checks for TNS do only work for common windows (which is always set)*/              for(w = 0; w < nWindows[0]; w++)              {                  if (isShortWindow[0]) diff --git a/libAACenc/src/qc_main.cpp b/libAACenc/src/qc_main.cpp index 9cd73f6..1025894 100644 --- a/libAACenc/src/qc_main.cpp +++ b/libAACenc/src/qc_main.cpp @@ -87,7 +87,7 @@ amm-info@iis.fraunhofer.de     contents/description: Quantizing & coding  ******************************************************************************/ - +#include <stdio.h>  #include "qc_main.h"  #include "quantize.h"  #include "interface.h" @@ -487,20 +487,24 @@ AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate(QC_STATE        *RESTRICT hQC,                                            INT              sampleRate,    /* output sampling rate */                                            INT              granuleLength) /* frame length */  { -  INT paddingOn; +  INT paddingOn=0;    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,                            &hQC->padding.paddingRest); +  //fprintf(stderr, "hQC->padding.paddingRest=%d bytes! (after)\n", hQC->padding.paddingRest);    frameLen = paddingOn + FDKaacEnc_calcFrameLen(bitRate,                                        sampleRate,                                        granuleLength,                                        FRAME_LEN_BYTES_INT); +  //fprintf(stderr, "frameLen=%d bytes!\n", frameLen); +    *avgTotalBits = frameLen<<3;    return AAC_ENC_OK; @@ -1377,7 +1381,7 @@ AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm,    /* Get total consumed bits in AU */    qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits  + qcOut->totFillBits +                       qcOut->elementExtBits + qcOut->globalExtBits; - +#if 1    if (qcKernel->bitrateMode==QCDATA_BR_MODE_CBR) {      /* Now we can get the exact transport bit amount, and hopefully it is equal to the estimated value */ @@ -1419,7 +1423,7 @@ AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm,      }    } /* MODE_CBR */ - +#endif    /* Update exact number of consumed header bits. */    qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits); @@ -1440,6 +1444,8 @@ AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm,                                                       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                     + qcOut->totFillBits + qcOut->globalExtBits -1)%8; diff --git a/libFDK/src/FDK_crc.cpp b/libFDK/src/FDK_crc.cpp index 17d47ad..a4c6900 100644 --- a/libFDK/src/FDK_crc.cpp +++ b/libFDK/src/FDK_crc.cpp @@ -87,7 +87,7 @@ amm-info@iis.fraunhofer.de     contents/description: CRC calculation  ******************************************************************************/ - +#include <stdio.h>  #include "FDK_crc.h" @@ -132,7 +132,7 @@ static const USHORT crcLookup_16_15_2_0[256] =    0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,    0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202  }; - +#if 1  /**   * \brief  This table defines precalculated lookup tables for crc polynom  x^16 + x^12 + x^5 + x^0.   */ @@ -171,7 +171,83 @@ static const USHORT crcLookup_16_12_5_0[256] =    0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,    0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0  }; +#else +static const USHORT crcLookup_16_12_5_0[256] = +{ +	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, +	0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, +	0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, +	0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, +	0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, +	0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, +	0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, +	0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, +	0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, +	0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, +	0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, +	0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, +	0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, +	0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, +	0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, +	0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, +	0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, +	0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, +	0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, +	0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, +	0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, +	0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, +	0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, +	0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, +	0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, +	0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, +	0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, +	0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, +	0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, +	0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, +	0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, +	0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 +}; +#endif + +/** + * \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, +};  /*--------------- function declarations --------------------*/ @@ -207,6 +283,10 @@ void FDKcrcInit(          )  {    /* 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^2 + x^0        (1) 1000 0000 0000 0101 -> 0x8005    x^16 + x^12 + x^5 + x^0        (1) 0001 0000 0010 0001 -> 0x1021    x^8 + x^4 + x^3 + x^2 + x^0              (1) 0001 1101 -> 0x001d */ @@ -228,6 +308,9 @@ void FDKcrcInit(        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 */ @@ -372,10 +455,9 @@ static inline INT calcCrc_Bytes(  {    int i;    USHORT crc = *pCrc; /* get crc value */ -    if (hBs!=NULL) {      for (i=0; i<nBytes; i++) { -      crc = (crc<<8)^pCrcLookup[((crc>>8)^((UCHAR)FDKreadBits(hBs,8)))&0xFF]; +    	crc = (crc<<8)^pCrcLookup[((crc>>8)^(FDKreadBits(hBs,8)))&0xFF];      }    }    else { @@ -385,6 +467,7 @@ static inline INT calcCrc_Bytes(    }    *pCrc = crc; /* update crc value */ +  //fprintf(stderr, "\n\n crc[%d]=%04x\n", i, crc);    return (i);  } @@ -420,7 +503,7 @@ static void crcCalc(    }    int bits, rBits; -  rBits = (rD->maxBits>=0) ? rD->maxBits : -rD->maxBits; /* ramaining bits */ +  rBits = (rD->maxBits>=0) ? rD->maxBits : -rD->maxBits; /* remaining bits */    if ((rD->maxBits>0) && (((INT)rD->bitBufCntBits>>3<<3)<rBits) ) {      bits = rD->bitBufCntBits;    } @@ -454,6 +537,7 @@ static void crcCalc(      }    } +  //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 f9121d1..a829485 100644 --- a/libFDK/src/FDK_tools_rom.cpp +++ b/libFDK/src/FDK_tools_rom.cpp @@ -2554,6 +2554,9 @@ const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epCo      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 (nChannels == 1) {          return &node_aac_sce; diff --git a/libFDK/src/fft.cpp b/libFDK/src/fft.cpp index 653a71a..ae3c98d 100644 --- a/libFDK/src/fft.cpp +++ b/libFDK/src/fft.cpp @@ -1078,7 +1078,8 @@ static inline void fft_apply_rot_vector(FIXP_DBL *RESTRICT pData, const int cl,    }  } -#define FFT_TWO_STAGE_MACRO_ENABLE +//FIXME:buggy for fft480 +//#define FFT_TWO_STAGE_MACRO_ENABLE  #ifdef FFT_TWO_STAGE_MACRO_ENABLE @@ -1154,7 +1155,7 @@ static inline void fft_apply_rot_vector(FIXP_DBL *RESTRICT pData, const int cl,  #else /* FFT_TWO_STAGE_MACRO_ENABLE */  /* select either switch case of function pointer. */ -//#define FFT_TWO_STAGE_SWITCH_CASE +#define FFT_TWO_STAGE_SWITCH_CASE  static inline void fftN2(          FIXP_DBL *pInput, @@ -1206,7 +1207,7 @@ static inline void fftN2(        case 16: fft_16(pDst); break;        case 32: fft_32(pDst); break;        /*case 64: fft_64(pDst); break;*/ -      case 128: fft_128(pDst); break; +      /*case 128: fft_128(pDst); break;*/      }  #endif      pSrc += 2; @@ -1245,7 +1246,7 @@ static inline void fftN2(        case 16: fft_16(pDst); break;        case 32: fft_32(pDst); break;        /*case 64: fft_64(pDst); break;*/ -      case 128: fft_128(pDst); break; +      /*case 128: fft_128(pDst); break;*/      }  #endif diff --git a/libFDK/src/mdct.cpp b/libFDK/src/mdct.cpp index 9a29aa1..9347a16 100644 --- a/libFDK/src/mdct.cpp +++ b/libFDK/src/mdct.cpp @@ -119,6 +119,9 @@ void imdct_gain(FIXP_DBL *pGain_m, int *pGain_e, int tl)    gain_e += -MDCT_OUTPUT_GAIN - log2_tl - MDCT_OUT_HEADROOM + 1; +  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 24fb32f..2c6f0c1 100644 --- a/libMpegTPEnc/src/tpenc_lib.cpp +++ b/libMpegTPEnc/src/tpenc_lib.cpp @@ -102,9 +102,9 @@ amm-info@iis.fraunhofer.de  #include "tpenc_adif.h" -#include "tpenc_latm.h" - +#include "tpenc_dab.h" +#include "tpenc_latm.h"  typedef struct {    int curSubFrame; @@ -128,6 +128,8 @@ struct TRANSPORTENC      ADIF_INFO adif; +    STRUCT_DAB dab; +      LATM_STREAM latm;      RAWPACKETS_INFO raw; @@ -203,6 +205,7 @@ static INT getPceRepetitionRate(            case TT_MP4_LOAS:                  /* PCE in ASC if chChonfig==0 */            case TT_MP4_LATM_MCP1:             /* PCE in ASC if chChonfig==0 */            case TT_DRM:                       /* PCE not allowed in DRM */ +          case TT_DABPLUS:            default:              pceFrameCounter = -1;            /* no PCE in raw_data_block */          } @@ -221,6 +224,7 @@ static INT getPceRepetitionRate(                pceFrameCounter = headerPeriod;                break;              case TT_DRM:                     /* PCE not allowed in DRM */ +            case TT_DABPLUS:              default:                pceFrameCounter = -1;          /* no PCE in raw_data_block */            } /* switch transportFmt */ @@ -287,6 +291,18 @@ TRANSPORTENC_ERROR transportEnc_Init(      }      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: @@ -383,6 +399,17 @@ TRANSPORTENC_ERROR transportEnc_WriteAccessUnit(                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: @@ -450,6 +477,9 @@ TRANSPORTENC_ERROR transportEnc_EndAccessUnit(HANDLE_TRANSPORTENC hTp, int *bits      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); @@ -484,6 +514,14 @@ TRANSPORTENC_ERROR transportEnc_GetFrame(HANDLE_TRANSPORTENC hTpEnc, int *nbytes          *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; @@ -518,6 +556,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: @@ -552,6 +593,9 @@ int transportEnc_CrcStartReg(HANDLE_TRANSPORTENC hTpEnc, int mBits)    case TT_MP4_ADTS:      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;    } @@ -565,6 +609,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;    } @@ -635,6 +682,7 @@ TRANSPORTENC_ERROR transportEnc_GetLibInfo( LIB_INFO *info )      | 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 4fcda51..06d7373 100644 --- a/libSBRenc/src/env_est.cpp +++ b/libSBRenc/src/env_est.cpp @@ -1147,6 +1147,7 @@ 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 71aab78..c7c5797 100644 --- a/libSBRenc/src/sbr_encoder.cpp +++ b/libSBRenc/src/sbr_encoder.cpp @@ -1939,7 +1939,7 @@ INT sbrEncoder_Init( -    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 98ded3b..9a787fb 100644 --- a/libSYS/include/FDK_audio.h +++ b/libSYS/include/FDK_audio.h @@ -134,7 +134,14 @@ 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. */ + +  TT_MP1_L1            = 16, /**< MPEG 1 Audio Layer 1 audio bitstream. */ +  TT_MP1_L2            = 17, /**< MPEG 1 Audio Layer 2 audio bitstream. */ +  TT_MP1_L3            = 18, /**< MPEG 1 Audio Layer 3 audio bitstream. */ + +  TT_RSVD50            = 50 /**< */  } TRANSPORT_TYPE; @@ -197,6 +204,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_DRM_AAC          = 143, /**< Virtual AOT for DRM (ER-AAC-SCAL without SBR)          */    AOT_DRM_SBR          = 144, /**< Virtual AOT for DRM (ER-AAC-SCAL with SBR)             */ | 
