Home | History | Annotate | Download | only in src
      1 
      2 /* -----------------------------------------------------------------------------------------------------------
      3 Software License for The Fraunhofer FDK AAC Codec Library for Android
      4 
      5  Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur Frderung der angewandten Forschung e.V.
      6   All rights reserved.
      7 
      8  1.    INTRODUCTION
      9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
     10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
     11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
     14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
     15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
     16 of the MPEG specifications.
     17 
     18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
     19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
     20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
     21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
     22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
     23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
     24 
     25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
     26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
     27 applications information and documentation.
     28 
     29 2.    COPYRIGHT LICENSE
     30 
     31 Redistribution and use in source and binary forms, with or without modification, are permitted without
     32 payment of copyright license fees provided that you satisfy the following conditions:
     33 
     34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
     35 your modifications thereto in source code form.
     36 
     37 You must retain the complete text of this software license in the documentation and/or other materials
     38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
     39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
     40 modifications thereto to recipients of copies in binary form.
     41 
     42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
     43 prior written permission.
     44 
     45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
     46 software or your modifications thereto.
     47 
     48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
     49 and the date of any change. For modified versions of the FDK AAC Codec, the term
     50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
     51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
     52 
     53 3.    NO PATENT LICENSE
     54 
     55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
     56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
     57 respect to this software.
     58 
     59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
     60 by appropriate patent licenses.
     61 
     62 4.    DISCLAIMER
     63 
     64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
     65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
     66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
     68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
     69 or business interruption, however caused and on any theory of liability, whether in contract, strict
     70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
     71 advised of the possibility of such damage.
     72 
     73 5.    CONTACT INFORMATION
     74 
     75 Fraunhofer Institute for Integrated Circuits IIS
     76 Attention: Audio and Multimedia Departments - FDK AAC LL
     77 Am Wolfsmantel 33
     78 91058 Erlangen, Germany
     79 
     80 www.iis.fraunhofer.de/amm
     81 amm-info (at) iis.fraunhofer.de
     82 ----------------------------------------------------------------------------------------------------------- */
     83 
     84 /**********************  Fraunhofer IIS FDK AAC Encoder lib  ******************
     85 
     86    Author(s): V. Bacigalupo
     87    Description: Metadata Encoder library interface functions
     88 
     89 ******************************************************************************/
     90 
     91 
     92 #include "metadata_main.h"
     93 #include "metadata_compressor.h"
     94 #include "FDK_bitstream.h"
     95 #include "FDK_audio.h"
     96 #include "genericStds.h"
     97 
     98 /*----------------- defines ----------------------*/
     99 #define MAX_DRC_BANDS        (1<<4)
    100 #define MAX_DRC_CHANNELS        (8)
    101 #define MAX_DRC_FRAMELEN   (2*1024)
    102 
    103 /*--------------- structure definitions --------------------*/
    104 
    105 typedef struct AAC_METADATA
    106 {
    107   /* MPEG: Dynamic Range Control */
    108   struct {
    109     UCHAR                         prog_ref_level_present;
    110     SCHAR                         prog_ref_level;
    111 
    112     UCHAR                         dyn_rng_sgn[MAX_DRC_BANDS];
    113     UCHAR                         dyn_rng_ctl[MAX_DRC_BANDS];
    114 
    115     UCHAR                         drc_bands_present;
    116     UCHAR                         drc_band_incr;
    117     UCHAR                         drc_band_top[MAX_DRC_BANDS];
    118     UCHAR                         drc_interpolation_scheme;
    119     AACENC_METADATA_DRC_PROFILE   drc_profile;
    120     INT                           drc_TargetRefLevel;    /* used for Limiter */
    121 
    122     /* excluded channels */
    123     UCHAR                         excluded_chns_present;
    124     UCHAR                         exclude_mask[2];       /* MAX_NUMBER_CHANNELS/8 */
    125   } mpegDrc;
    126 
    127   /* ETSI: addtl ancillary data */
    128   struct {
    129     /* Heavy Compression */
    130     UCHAR                         compression_on;        /* flag, if compression value should be written */
    131     UCHAR                         compression_value;     /* compression value */
    132     AACENC_METADATA_DRC_PROFILE   comp_profile;
    133     INT                           comp_TargetRefLevel;   /* used for Limiter */
    134     INT                           timecode_coarse_status;
    135     INT                           timecode_fine_status;
    136   } etsiAncData;
    137 
    138   SCHAR                         centerMixLevel;          /* center downmix level (0...7, according to table) */
    139   SCHAR                         surroundMixLevel;        /* surround downmix level (0...7, according to table) */
    140   UCHAR                         WritePCEMixDwnIdx;       /* flag */
    141   UCHAR                         DmxLvl_On;               /* flag */
    142 
    143   UCHAR                         dolbySurroundMode;
    144 
    145   UCHAR                         metadataMode;            /* indicate meta data mode in current frame (delay line) */
    146 
    147 } AAC_METADATA;
    148 
    149 struct FDK_METADATA_ENCODER
    150 {
    151   INT                metadataMode;
    152   HDRC_COMP          hDrcComp;
    153   AACENC_MetaData    submittedMetaData;
    154 
    155   INT                nAudioDataDelay;
    156   INT                nMetaDataDelay;
    157   INT                nChannels;
    158 
    159   INT_PCM            audioDelayBuffer[MAX_DRC_CHANNELS*MAX_DRC_FRAMELEN];
    160   int                audioDelayIdx;
    161 
    162   AAC_METADATA       metaDataBuffer[3];
    163   int                metaDataDelayIdx;
    164 
    165   UCHAR              drcInfoPayload[12];
    166   UCHAR              drcDsePayload[8];
    167 
    168   INT                matrix_mixdown_idx;
    169   AACENC_EXT_PAYLOAD exPayload[2];
    170   INT                nExtensions;
    171 
    172   INT                finalizeMetaData;                   /* Delay switch off by one frame and write default configuration to
    173                                                             finalize the metadata setup. */
    174 };
    175 
    176 
    177 /*---------------- constants -----------------------*/
    178 static const AACENC_MetaData defaultMetaDataSetup = {
    179     AACENC_METADATA_DRC_NONE,
    180     AACENC_METADATA_DRC_NONE,
    181     -(31<<16),
    182     -(31<<16),
    183     0,
    184     -(31<<16),
    185     0,
    186     0,
    187     0,
    188     0,
    189     0
    190 };
    191 
    192 static const FIXP_DBL dmxTable[8] = {
    193     ((FIXP_DBL)MAXVAL_DBL), FL2FXCONST_DBL(0.841f), FL2FXCONST_DBL(0.707f), FL2FXCONST_DBL(0.596f),
    194     FL2FXCONST_DBL(0.500f), FL2FXCONST_DBL(0.422f), FL2FXCONST_DBL(0.355f), FL2FXCONST_DBL(0.000f)
    195 };
    196 
    197 static const UCHAR surmix2matrix_mixdown_idx[8] = {
    198     0, 0, 0, 1, 1, 2, 2, 3
    199 };
    200 
    201 
    202 /*--------------- function declarations --------------------*/
    203 static FDK_METADATA_ERROR WriteMetadataPayload(
    204         const HANDLE_FDK_METADATA_ENCODER hMetaData,
    205         const AAC_METADATA * const  pMetadata
    206         );
    207 
    208 static INT WriteDynamicRangeInfoPayload(
    209         const AAC_METADATA* const pMetadata,
    210         UCHAR* const              pExtensionPayload
    211         );
    212 
    213 static INT WriteEtsiAncillaryDataPayload(
    214         const AAC_METADATA* const pMetadata,
    215         UCHAR* const              pExtensionPayload
    216         );
    217 
    218 static FDK_METADATA_ERROR CompensateAudioDelay(
    219         HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,
    220         INT_PCM * const             pAudioSamples,
    221         const INT                   nAudioSamples
    222         );
    223 
    224 static FDK_METADATA_ERROR LoadSubmittedMetadata(
    225         const AACENC_MetaData *   const hMetadata,
    226         const INT                       nChannels,
    227         const INT                       metadataMode,
    228         AAC_METADATA * const            pAacMetaData
    229         );
    230 
    231 static FDK_METADATA_ERROR ProcessCompressor(
    232         AAC_METADATA                    *pMetadata,
    233         HDRC_COMP                        hDrcComp,
    234         const INT_PCM * const            pSamples,
    235         const INT                        nSamples
    236         );
    237 
    238 /*------------- function definitions ----------------*/
    239 
    240 static DRC_PROFILE convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile)
    241 {
    242     DRC_PROFILE drcProfile = DRC_NONE;
    243 
    244     switch(aacProfile) {
    245       case AACENC_METADATA_DRC_NONE:          drcProfile = DRC_NONE;          break;
    246       case AACENC_METADATA_DRC_FILMSTANDARD:  drcProfile = DRC_FILMSTANDARD;  break;
    247       case AACENC_METADATA_DRC_FILMLIGHT:     drcProfile = DRC_FILMLIGHT;     break;
    248       case AACENC_METADATA_DRC_MUSICSTANDARD: drcProfile = DRC_MUSICSTANDARD; break;
    249       case AACENC_METADATA_DRC_MUSICLIGHT:    drcProfile = DRC_MUSICLIGHT;    break;
    250       case AACENC_METADATA_DRC_SPEECH:        drcProfile = DRC_SPEECH;        break;
    251       default:                                drcProfile = DRC_NONE;          break;
    252     }
    253     return drcProfile;
    254 }
    255 
    256 
    257 /* convert dialog normalization to program reference level */
    258 /* NOTE: this only is correct, if the decoder target level is set to -31dB for line mode / -20dB for RF mode */
    259 static UCHAR dialnorm2progreflvl(const INT d)
    260 {
    261     return ((UCHAR)FDKmax(0, FDKmin((-d + (1<<13)) >> 14, 127)));
    262 }
    263 
    264 /* convert program reference level to dialog normalization */
    265 static INT progreflvl2dialnorm(const UCHAR p)
    266 {
    267     return -((INT)(p<<(16-2)));
    268 }
    269 
    270 /* encode downmix levels to Downmixing_levels_MPEG4 */
    271 static SCHAR encodeDmxLvls(const SCHAR cmixlev, const SCHAR surmixlev)
    272 {
    273     SCHAR dmxLvls = 0;
    274     dmxLvls |= 0x80 | (cmixlev << 4); /* center_mix_level_on */
    275     dmxLvls |= 0x08 | surmixlev;      /* surround_mix_level_on */
    276 
    277     return dmxLvls;
    278 }
    279 
    280 /* encode AAC DRC gain (ISO/IEC 14496-3:2005  4.5.2.7) */
    281 static void encodeDynrng(INT gain, UCHAR* const dyn_rng_ctl, UCHAR* const dyn_rng_sgn )
    282 {
    283     if(gain < 0)
    284     {
    285       *dyn_rng_sgn = 1;
    286       gain = -gain;
    287     }
    288     else
    289     {
    290       *dyn_rng_sgn = 0;
    291     }
    292     gain = FDKmin(gain,(127<<14));
    293 
    294     *dyn_rng_ctl = (UCHAR)((gain + (1<<13)) >> 14);
    295 }
    296 
    297 /* decode AAC DRC gain (ISO/IEC 14496-3:2005  4.5.2.7) */
    298 static INT decodeDynrng(const UCHAR dyn_rng_ctl, const UCHAR dyn_rng_sgn)
    299 {
    300     INT tmp = ((INT)dyn_rng_ctl << (16-2));
    301     if (dyn_rng_sgn) tmp = -tmp;
    302 
    303     return tmp;
    304 }
    305 
    306 /* encode AAC compression value (ETSI TS 101 154 page 99) */
    307 static UCHAR encodeCompr(INT gain)
    308 {
    309     UCHAR x, y;
    310     INT tmp;
    311 
    312     /* tmp = (int)((48.164f - gain) / 6.0206f * 15 + 0.5f); */
    313     tmp = ((3156476 - gain) * 15 + 197283) / 394566;
    314 
    315     if (tmp >= 240) {
    316         return 0xFF;
    317     }
    318     else if (tmp < 0) {
    319         return 0;
    320     }
    321     else {
    322         x = tmp / 15;
    323         y = tmp % 15;
    324     }
    325 
    326     return (x << 4) | y;
    327 }
    328 
    329 /* decode AAC compression value (ETSI TS 101 154 page 99) */
    330 static INT decodeCompr(const UCHAR compr)
    331 {
    332     INT gain;
    333     SCHAR x = compr >> 4;     /* 4 MSB of compr */
    334     UCHAR y = (compr & 0x0F); /* 4 LSB of compr */
    335 
    336     /* gain = (INT)((48.164f - 6.0206f * x - 0.4014f * y) ); */
    337     gain = (INT)( scaleValue(((LONG)FL2FXCONST_DBL(6.0206f/128.f)*(8-x) - (LONG)FL2FXCONST_DBL(0.4014f/128.f)*y), -(DFRACT_BITS-1-7-16)) );
    338 
    339     return gain;
    340 }
    341 
    342 
    343 FDK_METADATA_ERROR FDK_MetadataEnc_Open(
    344         HANDLE_FDK_METADATA_ENCODER *phMetaData
    345         )
    346 {
    347     FDK_METADATA_ERROR err = METADATA_OK;
    348     HANDLE_FDK_METADATA_ENCODER hMetaData = NULL;
    349 
    350     if (phMetaData == NULL) {
    351       err = METADATA_INVALID_HANDLE;
    352       goto bail;
    353     }
    354 
    355     /* allocate memory */
    356     hMetaData = (HANDLE_FDK_METADATA_ENCODER) FDKcalloc(1, sizeof(FDK_METADATA_ENCODER) );
    357 
    358     if (hMetaData == NULL) {
    359       err = METADATA_MEMORY_ERROR;
    360       goto bail;
    361     }
    362 
    363     FDKmemclear(hMetaData, sizeof(FDK_METADATA_ENCODER));
    364 
    365     /* Allocate DRC Compressor. */
    366     if (FDK_DRC_Generator_Open(&hMetaData->hDrcComp)!=0) {
    367       err = METADATA_MEMORY_ERROR;
    368       goto bail;
    369     }
    370 
    371     /* Return metadata instance */
    372     *phMetaData = hMetaData;
    373 
    374     return err;
    375 
    376 bail:
    377     FDK_MetadataEnc_Close(&hMetaData);
    378     return err;
    379 }
    380 
    381 FDK_METADATA_ERROR FDK_MetadataEnc_Close(
    382         HANDLE_FDK_METADATA_ENCODER *phMetaData
    383         )
    384 {
    385     FDK_METADATA_ERROR err = METADATA_OK;
    386 
    387     if (phMetaData == NULL) {
    388       err = METADATA_INVALID_HANDLE;
    389       goto bail;
    390     }
    391 
    392     if (*phMetaData != NULL) {
    393       FDK_DRC_Generator_Close(&(*phMetaData)->hDrcComp);
    394       FDKfree(*phMetaData);
    395       *phMetaData = NULL;
    396     }
    397 bail:
    398     return err;
    399 }
    400 
    401 FDK_METADATA_ERROR FDK_MetadataEnc_Init(
    402         HANDLE_FDK_METADATA_ENCODER hMetaData,
    403         const INT                   resetStates,
    404         const INT                   metadataMode,
    405         const INT                   audioDelay,
    406         const UINT                  frameLength,
    407         const UINT                  sampleRate,
    408         const UINT                  nChannels,
    409         const CHANNEL_MODE          channelMode,
    410         const CHANNEL_ORDER         channelOrder
    411         )
    412 {
    413     FDK_METADATA_ERROR err = METADATA_OK;
    414     int i, nFrames, delay;
    415 
    416     if (hMetaData==NULL) {
    417       err = METADATA_INVALID_HANDLE;
    418       goto bail;
    419     }
    420 
    421     /* Determine values for delay compensation. */
    422     for (nFrames=0, delay=audioDelay-frameLength; delay>0; delay-=frameLength, nFrames++);
    423 
    424     if ( (hMetaData->nChannels>MAX_DRC_CHANNELS) || ((-delay)>MAX_DRC_FRAMELEN) ) {
    425       err = METADATA_INIT_ERROR;
    426       goto bail;
    427     }
    428 
    429     /* Initialize with default setup. */
    430     FDKmemcpy(&hMetaData->submittedMetaData, &defaultMetaDataSetup,  sizeof(AACENC_MetaData));
    431 
    432     hMetaData->finalizeMetaData = 0; /* finalize meta data only while on/off switching, else disabled */
    433 
    434     /* Reset delay lines. */
    435     if ( resetStates || (hMetaData->nAudioDataDelay!=-delay) || (hMetaData->nChannels!=(INT)nChannels) )
    436     {
    437       FDKmemclear(hMetaData->audioDelayBuffer, sizeof(hMetaData->audioDelayBuffer));
    438       FDKmemclear(hMetaData->metaDataBuffer, sizeof(hMetaData->metaDataBuffer));
    439       hMetaData->audioDelayIdx = 0;
    440       hMetaData->metaDataDelayIdx = 0;
    441     }
    442     else {
    443       /* Enable meta data. */
    444       if ( (hMetaData->metadataMode==0) && (metadataMode!=0) ) {
    445         /* disable meta data in all delay lines */
    446         for (i=0; i<(int)(sizeof(hMetaData->metaDataBuffer)/sizeof(AAC_METADATA)); i++) {
    447           LoadSubmittedMetadata(&hMetaData->submittedMetaData, nChannels, 0, &hMetaData->metaDataBuffer[i]);
    448         }
    449       }
    450 
    451       /* Disable meta data.*/
    452       if ( (hMetaData->metadataMode!=0) && (metadataMode==0) ) {
    453         hMetaData->finalizeMetaData = hMetaData->metadataMode;
    454       }
    455     }
    456 
    457     /* Initialize delay. */
    458     hMetaData->nAudioDataDelay = -delay;
    459     hMetaData->nMetaDataDelay  = nFrames;
    460     hMetaData->nChannels       = nChannels;
    461     hMetaData->metadataMode    = metadataMode;
    462 
    463     /* Initialize compressor. */
    464     if (metadataMode != 0) {
    465         if ( FDK_DRC_Generator_Initialize(
    466                          hMetaData->hDrcComp,
    467                          DRC_NONE,
    468                          DRC_NONE,
    469                          frameLength,
    470                          sampleRate,
    471                          channelMode,
    472                          channelOrder,
    473                          1) != 0)
    474         {
    475           err = METADATA_INIT_ERROR;
    476         }
    477     }
    478 bail:
    479     return err;
    480 }
    481 
    482 static FDK_METADATA_ERROR ProcessCompressor(
    483         AAC_METADATA                    *pMetadata,
    484         HDRC_COMP                        hDrcComp,
    485         const INT_PCM * const            pSamples,
    486         const INT                        nSamples
    487         )
    488 {
    489     FDK_METADATA_ERROR err = METADATA_OK;
    490 
    491     INT dynrng, compr;
    492     DRC_PROFILE profileDrc  = convertProfile(pMetadata->mpegDrc.drc_profile);
    493     DRC_PROFILE profileComp = convertProfile(pMetadata->etsiAncData.comp_profile);
    494 
    495     if ( (pMetadata==NULL) || (hDrcComp==NULL) ) {
    496       err = METADATA_INVALID_HANDLE;
    497       return err;
    498     }
    499 
    500     /* first, check if profile is same as last frame
    501      * otherwise, update setup */
    502     if ( (profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp))
    503       || (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp)) )
    504     {
    505       FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp);
    506     }
    507 
    508     /* Sanity check */
    509     if (profileComp == DRC_NONE) {
    510       pMetadata->etsiAncData.compression_value = 0x80;  /* to ensure no external values will be written if not configured */
    511     }
    512 
    513     /* in case of embedding external values, copy this now (limiter may overwrite them) */
    514     dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0], pMetadata->mpegDrc.dyn_rng_sgn[0]);
    515     compr  = decodeCompr(pMetadata->etsiAncData.compression_value);
    516 
    517     /* Call compressor */
    518     if (FDK_DRC_Generator_Calc(hDrcComp,
    519                            pSamples,
    520                            progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level),
    521                            pMetadata->mpegDrc.drc_TargetRefLevel,
    522                            pMetadata->etsiAncData.comp_TargetRefLevel,
    523                            dmxTable[pMetadata->centerMixLevel],
    524                            dmxTable[pMetadata->surroundMixLevel],
    525                            &dynrng,
    526                            &compr) != 0)
    527     {
    528       err = METADATA_ENCODE_ERROR;
    529       goto bail;
    530     }
    531 
    532     /* Write DRC values */
    533     pMetadata->mpegDrc.drc_band_incr = 0;
    534     encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl, pMetadata->mpegDrc.dyn_rng_sgn);
    535     pMetadata->etsiAncData.compression_value = encodeCompr(compr);
    536 
    537 bail:
    538     return err;
    539 }
    540 
    541 FDK_METADATA_ERROR FDK_MetadataEnc_Process(
    542         HANDLE_FDK_METADATA_ENCODER      hMetaDataEnc,
    543         INT_PCM * const                  pAudioSamples,
    544         const INT                        nAudioSamples,
    545         const AACENC_MetaData * const    pMetadata,
    546         AACENC_EXT_PAYLOAD **            ppMetaDataExtPayload,
    547         UINT *                           nMetaDataExtensions,
    548         INT *                            matrix_mixdown_idx
    549         )
    550 {
    551     FDK_METADATA_ERROR err = METADATA_OK;
    552     int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode;
    553 
    554     /* Where to write new meta data info */
    555     metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx;
    556 
    557     /* How to write the data */
    558     metadataMode = hMetaDataEnc->metadataMode;
    559 
    560     /* Compensate meta data delay. */
    561     hMetaDataEnc->metaDataDelayIdx++;
    562     if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay) hMetaDataEnc->metaDataDelayIdx = 0;
    563 
    564     /* Where to read pending meta data info from. */
    565     metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx;
    566 
    567     /* Submit new data if available. */
    568     if (pMetadata!=NULL) {
    569         FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata, sizeof(AACENC_MetaData));
    570     }
    571 
    572     /* Write one additional frame with default configuration of meta data. Ensure defined behaviour on decoder side. */
    573     if ( (hMetaDataEnc->finalizeMetaData!=0) && (hMetaDataEnc->metadataMode==0)) {
    574       FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup,  sizeof(AACENC_MetaData));
    575       metadataMode = hMetaDataEnc->finalizeMetaData;
    576       hMetaDataEnc->finalizeMetaData = 0;
    577     }
    578 
    579     /* Get last submitted data. */
    580     if ( (err = LoadSubmittedMetadata(
    581                         &hMetaDataEnc->submittedMetaData,
    582                          hMetaDataEnc->nChannels,
    583                          metadataMode,
    584                         &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) != METADATA_OK )
    585     {
    586         goto bail;
    587     }
    588 
    589     /* Calculate compressor if necessary and updata meta data info */
    590     if (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode != 0) {
    591       if ( (err = ProcessCompressor(
    592                         &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
    593                          hMetaDataEnc->hDrcComp,
    594                          pAudioSamples,
    595                          nAudioSamples)) != METADATA_OK)
    596       {
    597         /* Get last submitted data again. */
    598         LoadSubmittedMetadata(
    599                         &hMetaDataEnc->submittedMetaData,
    600                          hMetaDataEnc->nChannels,
    601                          metadataMode,
    602                         &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]);
    603       }
    604     }
    605 
    606     /* Convert Meta Data side info to bitstream data. */
    607     if ( (err = WriteMetadataPayload(hMetaDataEnc, &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) != METADATA_OK ) {
    608       goto bail;
    609     }
    610 
    611     /* Assign meta data to output */
    612     *ppMetaDataExtPayload = hMetaDataEnc->exPayload;
    613     *nMetaDataExtensions  = hMetaDataEnc->nExtensions;
    614     *matrix_mixdown_idx   = hMetaDataEnc->matrix_mixdown_idx;
    615 
    616 bail:
    617     /* Compensate audio delay, reset err status. */
    618     err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, nAudioSamples);
    619 
    620     return err;
    621 }
    622 
    623 
    624 static FDK_METADATA_ERROR CompensateAudioDelay(
    625         HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,
    626         INT_PCM * const             pAudioSamples,
    627         const INT                   nAudioSamples
    628         )
    629 {
    630     FDK_METADATA_ERROR err = METADATA_OK;
    631 
    632     if (hMetaDataEnc->nAudioDataDelay) {
    633       int i, delaySamples = hMetaDataEnc->nAudioDataDelay*hMetaDataEnc->nChannels;
    634 
    635       for (i = 0; i < nAudioSamples; i++) {
    636         INT_PCM tmp = pAudioSamples[i];
    637         pAudioSamples[i] = hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx];
    638         hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx] = tmp;
    639 
    640         hMetaDataEnc->audioDelayIdx++;
    641         if (hMetaDataEnc->audioDelayIdx >= delaySamples) hMetaDataEnc->audioDelayIdx = 0;
    642       }
    643     }
    644 
    645     return err;
    646 }
    647 
    648 /*-----------------------------------------------------------------------------
    649 
    650   functionname: WriteMetadataPayload
    651   description:  fills anc data and extension payload
    652   returns:      Error status
    653 
    654  ------------------------------------------------------------------------------*/
    655 static FDK_METADATA_ERROR WriteMetadataPayload(
    656         const HANDLE_FDK_METADATA_ENCODER hMetaData,
    657         const AAC_METADATA * const        pMetadata
    658         )
    659 {
    660     FDK_METADATA_ERROR err = METADATA_OK;
    661 
    662     if ( (hMetaData==NULL) || (pMetadata==NULL) ) {
    663         err = METADATA_INVALID_HANDLE;
    664         goto bail;
    665     }
    666 
    667     hMetaData->nExtensions = 0;
    668     hMetaData->matrix_mixdown_idx = -1;
    669 
    670     /* AAC-DRC */
    671     if (pMetadata->metadataMode != 0)
    672     {
    673         hMetaData->exPayload[hMetaData->nExtensions].pData               = hMetaData->drcInfoPayload;
    674         hMetaData->exPayload[hMetaData->nExtensions].dataType            = EXT_DYNAMIC_RANGE;
    675         hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
    676 
    677         hMetaData->exPayload[hMetaData->nExtensions].dataSize =
    678               WriteDynamicRangeInfoPayload(pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
    679 
    680         hMetaData->nExtensions++;
    681 
    682         /* Matrix Mixdown Coefficient in PCE */
    683         if (pMetadata->WritePCEMixDwnIdx) {
    684             hMetaData->matrix_mixdown_idx = surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel];
    685         }
    686 
    687         /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */
    688         if (pMetadata->metadataMode == 2) /* MP4_METADATA_MPEG_ETSI */
    689         {
    690             hMetaData->exPayload[hMetaData->nExtensions].pData               = hMetaData->drcDsePayload;
    691             hMetaData->exPayload[hMetaData->nExtensions].dataType            = EXT_DATA_ELEMENT;
    692             hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
    693 
    694             hMetaData->exPayload[hMetaData->nExtensions].dataSize =
    695                  WriteEtsiAncillaryDataPayload(pMetadata,hMetaData->exPayload[hMetaData->nExtensions].pData);
    696 
    697             hMetaData->nExtensions++;
    698         } /* metadataMode == 2 */
    699 
    700     } /* metadataMode != 0 */
    701 
    702 bail:
    703     return err;
    704 }
    705 
    706 static INT WriteDynamicRangeInfoPayload(
    707         const AAC_METADATA* const pMetadata,
    708         UCHAR* const              pExtensionPayload
    709         )
    710 {
    711     const INT pce_tag_present = 0;        /* yet fixed setting! */
    712     const INT prog_ref_lev_res_bits = 0;
    713     INT i, drc_num_bands = 1;
    714 
    715     FDK_BITSTREAM bsWriter;
    716     FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
    717 
    718     /* dynamic_range_info() */
    719     FDKwriteBits(&bsWriter, pce_tag_present, 1);                                         /* pce_tag_present */
    720     if (pce_tag_present) {
    721       FDKwriteBits(&bsWriter, 0x0, 4);                                                   /* pce_instance_tag */
    722       FDKwriteBits(&bsWriter, 0x0, 4);                                                   /* drc_tag_reserved_bits */
    723    }
    724 
    725     /* Exclude channels */
    726     FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0, 1);      /* excluded_chns_present*/
    727 
    728     /* Multiband DRC */
    729     FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0, 1);          /* drc_bands_present */
    730     if (pMetadata->mpegDrc.drc_bands_present)
    731     {
    732       FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr, 4);                      /* drc_band_incr */
    733       FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme, 4);           /* drc_interpolation_scheme */
    734       drc_num_bands += pMetadata->mpegDrc.drc_band_incr;
    735       for (i=0; i<drc_num_bands; i++) {
    736         FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i], 8);                  /* drc_band_top */
    737       }
    738     }
    739 
    740     /* Program Reference Level */
    741     FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present, 1);               /* prog_ref_level_present */
    742     if (pMetadata->mpegDrc.prog_ref_level_present)
    743     {
    744       FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level, 7);                     /* prog_ref_level */
    745       FDKwriteBits(&bsWriter, prog_ref_lev_res_bits, 1);                                 /* prog_ref_level_reserved_bits */
    746     }
    747 
    748     /* DRC Values */
    749     for (i=0; i<drc_num_bands; i++) {
    750       FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0, 1);           /* dyn_rng_sgn[ */
    751       FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i], 7);                     /* dyn_rng_ctl */
    752     }
    753 
    754     /* return number of valid bits in extension payload. */
    755     return FDKgetValidBits(&bsWriter);
    756 }
    757 
    758 static INT WriteEtsiAncillaryDataPayload(
    759         const AAC_METADATA* const pMetadata,
    760         UCHAR* const              pExtensionPayload
    761         )
    762 {
    763     FDK_BITSTREAM bsWriter;
    764     FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
    765 
    766     /* ancillary_data_sync */
    767     FDKwriteBits(&bsWriter, 0xBC, 8);
    768 
    769     /* bs_info */
    770     FDKwriteBits(&bsWriter, 0x3, 2);                                                     /* mpeg_audio_type */
    771     FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode, 2);                            /* dolby_surround_mode */
    772     FDKwriteBits(&bsWriter, 0x0, 4);                                                     /* reserved */
    773 
    774     /* ancillary_data_status */
    775     FDKwriteBits(&bsWriter, 0, 3);                                                       /* 3 bit Reserved, set to "0" */
    776     FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0, 1);                          /* downmixing_levels_MPEG4_status */
    777     FDKwriteBits(&bsWriter, 0, 1);                                                       /* Reserved, set to "0" */
    778     FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0, 1);         /* audio_coding_mode_and_compression status */
    779     FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0, 1); /* coarse_grain_timecode_status */
    780     FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0, 1);   /* fine_grain_timecode_status */
    781 
    782     /* downmixing_levels_MPEG4_status */
    783     if (pMetadata->DmxLvl_On) {
    784       FDKwriteBits(&bsWriter, encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel), 8);
    785     }
    786 
    787     /* audio_coding_mode_and_compression_status */
    788     if (pMetadata->etsiAncData.compression_on) {
    789       FDKwriteBits(&bsWriter, 0x01, 8);                                                  /* audio coding mode */
    790       FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value, 8);              /* compression value */
    791     }
    792 
    793     /* grain-timecode coarse/fine */
    794     if (pMetadata->etsiAncData.timecode_coarse_status) {
    795       FDKwriteBits(&bsWriter, 0x0, 16);                                                  /* not yet supported */
    796     }
    797 
    798     if (pMetadata->etsiAncData.timecode_fine_status) {
    799       FDKwriteBits(&bsWriter, 0x0, 16);                                                  /* not yet supported */
    800     }
    801 
    802     return FDKgetValidBits(&bsWriter);
    803 }
    804 
    805 
    806 static FDK_METADATA_ERROR LoadSubmittedMetadata(
    807         const AACENC_MetaData * const   hMetadata,
    808         const INT                       nChannels,
    809         const INT                       metadataMode,
    810         AAC_METADATA * const            pAacMetaData
    811         )
    812 {
    813     FDK_METADATA_ERROR err = METADATA_OK;
    814 
    815     if (pAacMetaData==NULL) {
    816       err = METADATA_INVALID_HANDLE;
    817     }
    818     else {
    819       /* init struct */
    820       FDKmemclear(pAacMetaData, sizeof(AAC_METADATA));
    821 
    822       if (hMetadata!=NULL) {
    823         /* convert data */
    824         pAacMetaData->mpegDrc.drc_profile            = hMetadata->drc_profile;
    825         pAacMetaData->etsiAncData.comp_profile       = hMetadata->comp_profile;
    826         pAacMetaData->mpegDrc.drc_TargetRefLevel     = hMetadata->drc_TargetRefLevel;
    827         pAacMetaData->etsiAncData.comp_TargetRefLevel= hMetadata->comp_TargetRefLevel;
    828         pAacMetaData->mpegDrc.prog_ref_level_present = hMetadata->prog_ref_level_present;
    829         pAacMetaData->mpegDrc.prog_ref_level         = dialnorm2progreflvl(hMetadata->prog_ref_level);
    830 
    831         pAacMetaData->centerMixLevel                 = hMetadata->centerMixLevel;
    832         pAacMetaData->surroundMixLevel               = hMetadata->surroundMixLevel;
    833         pAacMetaData->WritePCEMixDwnIdx              = hMetadata->PCE_mixdown_idx_present;
    834         pAacMetaData->DmxLvl_On                      = hMetadata->ETSI_DmxLvl_present;
    835 
    836         pAacMetaData->etsiAncData.compression_on = 1;
    837 
    838 
    839         if (nChannels == 2) {
    840           pAacMetaData->dolbySurroundMode = hMetadata->dolbySurroundMode;     /* dolby_surround_mode */
    841         } else {
    842           pAacMetaData->dolbySurroundMode = 0;
    843         }
    844 
    845         pAacMetaData->etsiAncData.timecode_coarse_status = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */
    846         pAacMetaData->etsiAncData.timecode_fine_status   = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */
    847 
    848         pAacMetaData->metadataMode = metadataMode;
    849       }
    850       else {
    851         pAacMetaData->metadataMode = 0;                      /* there is no configuration available */
    852       }
    853     }
    854 
    855     return err;
    856 }
    857 
    858 INT FDK_MetadataEnc_GetDelay(
    859         HANDLE_FDK_METADATA_ENCODER hMetadataEnc
    860         )
    861 {
    862     INT delay = 0;
    863 
    864     if (hMetadataEnc!=NULL) {
    865         delay = hMetadataEnc->nAudioDataDelay;
    866     }
    867 
    868     return delay;
    869 }
    870 
    871 
    872