1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5� Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6  All rights reserved.
7
8 1.    INTRODUCTION
9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16of the MPEG specifications.
17
18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20individually for the purpose of encoding or decoding bit streams in products that are compliant with
21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27applications information and documentation.
28
292.    COPYRIGHT LICENSE
30
31Redistribution and use in source and binary forms, with or without modification, are permitted without
32payment of copyright license fees provided that you satisfy the following conditions:
33
34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35your modifications thereto in source code form.
36
37You must retain the complete text of this software license in the documentation and/or other materials
38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40modifications thereto to recipients of copies in binary form.
41
42The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43prior written permission.
44
45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46software or your modifications thereto.
47
48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49and 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
533.    NO PATENT LICENSE
54
55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57respect to this software.
58
59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60by appropriate patent licenses.
61
624.    DISCLAIMER
63
64This 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
66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69or business interruption, however caused and on any theory of liability, whether in contract, strict
70liability, or tort (including negligence), arising in any way out of the use of this software, even if
71advised of the possibility of such damage.
72
735.    CONTACT INFORMATION
74
75Fraunhofer Institute for Integrated Circuits IIS
76Attention: Audio and Multimedia Departments - FDK AAC LL
77Am Wolfsmantel 33
7891058 Erlangen, Germany
79
80www.iis.fraunhofer.de/amm
81amm-info@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
105typedef 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
149struct 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 -----------------------*/
178static 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
192static 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
197static const UCHAR surmix2matrix_mixdown_idx[8] = {
198    0, 0, 0, 1, 1, 2, 2, 3
199};
200
201
202/*--------------- function declarations --------------------*/
203static FDK_METADATA_ERROR WriteMetadataPayload(
204        const HANDLE_FDK_METADATA_ENCODER hMetaData,
205        const AAC_METADATA * const  pMetadata
206        );
207
208static INT WriteDynamicRangeInfoPayload(
209        const AAC_METADATA* const pMetadata,
210        UCHAR* const              pExtensionPayload
211        );
212
213static INT WriteEtsiAncillaryDataPayload(
214        const AAC_METADATA* const pMetadata,
215        UCHAR* const              pExtensionPayload
216        );
217
218static FDK_METADATA_ERROR CompensateAudioDelay(
219        HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,
220        INT_PCM * const             pAudioSamples,
221        const INT                   nAudioSamples
222        );
223
224static 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
231static 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
240static 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 */
259static 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 */
265static INT progreflvl2dialnorm(const UCHAR p)
266{
267    return -((INT)(p<<(16-2)));
268}
269
270/* encode downmix levels to Downmixing_levels_MPEG4 */
271static 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) */
281static 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) */
298static 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) */
307static 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) */
330static 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
343FDK_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
376bail:
377    FDK_MetadataEnc_Close(&hMetaData);
378    return err;
379}
380
381FDK_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    }
397bail:
398    return err;
399}
400
401FDK_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    }
478bail:
479    return err;
480}
481
482static 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    if ( (pMetadata==NULL) || (hDrcComp==NULL) ) {
492      err = METADATA_INVALID_HANDLE;
493      return err;
494    }
495    DRC_PROFILE profileDrc  = convertProfile(pMetadata->mpegDrc.drc_profile);
496    DRC_PROFILE profileComp = convertProfile(pMetadata->etsiAncData.comp_profile);
497
498    /* first, check if profile is same as last frame
499     * otherwise, update setup */
500    if ( (profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp))
501      || (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp)) )
502    {
503      FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp);
504    }
505
506    /* Sanity check */
507    if (profileComp == DRC_NONE) {
508      pMetadata->etsiAncData.compression_value = 0x80;  /* to ensure no external values will be written if not configured */
509    }
510
511    /* in case of embedding external values, copy this now (limiter may overwrite them) */
512    INT dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0], pMetadata->mpegDrc.dyn_rng_sgn[0]);
513    INT compr  = decodeCompr(pMetadata->etsiAncData.compression_value);
514
515    /* Call compressor */
516    if (FDK_DRC_Generator_Calc(hDrcComp,
517                           pSamples,
518                           progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level),
519                           pMetadata->mpegDrc.drc_TargetRefLevel,
520                           pMetadata->etsiAncData.comp_TargetRefLevel,
521                           dmxTable[pMetadata->centerMixLevel],
522                           dmxTable[pMetadata->surroundMixLevel],
523                           &dynrng,
524                           &compr) != 0)
525    {
526      err = METADATA_ENCODE_ERROR;
527      goto bail;
528    }
529
530    /* Write DRC values */
531    pMetadata->mpegDrc.drc_band_incr = 0;
532    encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl, pMetadata->mpegDrc.dyn_rng_sgn);
533    pMetadata->etsiAncData.compression_value = encodeCompr(compr);
534
535bail:
536    return err;
537}
538
539FDK_METADATA_ERROR FDK_MetadataEnc_Process(
540        HANDLE_FDK_METADATA_ENCODER      hMetaDataEnc,
541        INT_PCM * const                  pAudioSamples,
542        const INT                        nAudioSamples,
543        const AACENC_MetaData * const    pMetadata,
544        AACENC_EXT_PAYLOAD **            ppMetaDataExtPayload,
545        UINT *                           nMetaDataExtensions,
546        INT *                            matrix_mixdown_idx
547        )
548{
549    FDK_METADATA_ERROR err = METADATA_OK;
550    int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode;
551
552    /* Where to write new meta data info */
553    metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx;
554
555    /* How to write the data */
556    metadataMode = hMetaDataEnc->metadataMode;
557
558    /* Compensate meta data delay. */
559    hMetaDataEnc->metaDataDelayIdx++;
560    if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay) hMetaDataEnc->metaDataDelayIdx = 0;
561
562    /* Where to read pending meta data info from. */
563    metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx;
564
565    /* Submit new data if available. */
566    if (pMetadata!=NULL) {
567        FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata, sizeof(AACENC_MetaData));
568    }
569
570    /* Write one additional frame with default configuration of meta data. Ensure defined behaviour on decoder side. */
571    if ( (hMetaDataEnc->finalizeMetaData!=0) && (hMetaDataEnc->metadataMode==0)) {
572      FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup,  sizeof(AACENC_MetaData));
573      metadataMode = hMetaDataEnc->finalizeMetaData;
574      hMetaDataEnc->finalizeMetaData = 0;
575    }
576
577    /* Get last submitted data. */
578    if ( (err = LoadSubmittedMetadata(
579                        &hMetaDataEnc->submittedMetaData,
580                         hMetaDataEnc->nChannels,
581                         metadataMode,
582                        &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) != METADATA_OK )
583    {
584        goto bail;
585    }
586
587    /* Calculate compressor if necessary and updata meta data info */
588    if (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode != 0) {
589      if ( (err = ProcessCompressor(
590                        &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx],
591                         hMetaDataEnc->hDrcComp,
592                         pAudioSamples,
593                         nAudioSamples)) != METADATA_OK)
594      {
595        /* Get last submitted data again. */
596        LoadSubmittedMetadata(
597                        &hMetaDataEnc->submittedMetaData,
598                         hMetaDataEnc->nChannels,
599                         metadataMode,
600                        &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]);
601      }
602    }
603
604    /* Convert Meta Data side info to bitstream data. */
605    if ( (err = WriteMetadataPayload(hMetaDataEnc, &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) != METADATA_OK ) {
606      goto bail;
607    }
608
609    /* Assign meta data to output */
610    *ppMetaDataExtPayload = hMetaDataEnc->exPayload;
611    *nMetaDataExtensions  = hMetaDataEnc->nExtensions;
612    *matrix_mixdown_idx   = hMetaDataEnc->matrix_mixdown_idx;
613
614bail:
615    /* Compensate audio delay, reset err status. */
616    err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, nAudioSamples);
617
618    return err;
619}
620
621
622static FDK_METADATA_ERROR CompensateAudioDelay(
623        HANDLE_FDK_METADATA_ENCODER hMetaDataEnc,
624        INT_PCM * const             pAudioSamples,
625        const INT                   nAudioSamples
626        )
627{
628    FDK_METADATA_ERROR err = METADATA_OK;
629
630    if (hMetaDataEnc->nAudioDataDelay) {
631      int i, delaySamples = hMetaDataEnc->nAudioDataDelay*hMetaDataEnc->nChannels;
632
633      for (i = 0; i < nAudioSamples; i++) {
634        INT_PCM tmp = pAudioSamples[i];
635        pAudioSamples[i] = hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx];
636        hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx] = tmp;
637
638        hMetaDataEnc->audioDelayIdx++;
639        if (hMetaDataEnc->audioDelayIdx >= delaySamples) hMetaDataEnc->audioDelayIdx = 0;
640      }
641    }
642
643    return err;
644}
645
646/*-----------------------------------------------------------------------------
647
648  functionname: WriteMetadataPayload
649  description:  fills anc data and extension payload
650  returns:      Error status
651
652 ------------------------------------------------------------------------------*/
653static FDK_METADATA_ERROR WriteMetadataPayload(
654        const HANDLE_FDK_METADATA_ENCODER hMetaData,
655        const AAC_METADATA * const        pMetadata
656        )
657{
658    FDK_METADATA_ERROR err = METADATA_OK;
659
660    if ( (hMetaData==NULL) || (pMetadata==NULL) ) {
661        err = METADATA_INVALID_HANDLE;
662        goto bail;
663    }
664
665    hMetaData->nExtensions = 0;
666    hMetaData->matrix_mixdown_idx = -1;
667
668    /* AAC-DRC */
669    if (pMetadata->metadataMode != 0)
670    {
671        hMetaData->exPayload[hMetaData->nExtensions].pData               = hMetaData->drcInfoPayload;
672        hMetaData->exPayload[hMetaData->nExtensions].dataType            = EXT_DYNAMIC_RANGE;
673        hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
674
675        hMetaData->exPayload[hMetaData->nExtensions].dataSize =
676              WriteDynamicRangeInfoPayload(pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData);
677
678        hMetaData->nExtensions++;
679
680        /* Matrix Mixdown Coefficient in PCE */
681        if (pMetadata->WritePCEMixDwnIdx) {
682            hMetaData->matrix_mixdown_idx = surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel];
683        }
684
685        /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */
686        if (pMetadata->metadataMode == 2) /* MP4_METADATA_MPEG_ETSI */
687        {
688            hMetaData->exPayload[hMetaData->nExtensions].pData               = hMetaData->drcDsePayload;
689            hMetaData->exPayload[hMetaData->nExtensions].dataType            = EXT_DATA_ELEMENT;
690            hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1;
691
692            hMetaData->exPayload[hMetaData->nExtensions].dataSize =
693                 WriteEtsiAncillaryDataPayload(pMetadata,hMetaData->exPayload[hMetaData->nExtensions].pData);
694
695            hMetaData->nExtensions++;
696        } /* metadataMode == 2 */
697
698    } /* metadataMode != 0 */
699
700bail:
701    return err;
702}
703
704static INT WriteDynamicRangeInfoPayload(
705        const AAC_METADATA* const pMetadata,
706        UCHAR* const              pExtensionPayload
707        )
708{
709    const INT pce_tag_present = 0;        /* yet fixed setting! */
710    const INT prog_ref_lev_res_bits = 0;
711    INT i, drc_num_bands = 1;
712
713    FDK_BITSTREAM bsWriter;
714    FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
715
716    /* dynamic_range_info() */
717    FDKwriteBits(&bsWriter, pce_tag_present, 1);                                         /* pce_tag_present */
718    if (pce_tag_present) {
719      FDKwriteBits(&bsWriter, 0x0, 4);                                                   /* pce_instance_tag */
720      FDKwriteBits(&bsWriter, 0x0, 4);                                                   /* drc_tag_reserved_bits */
721   }
722
723    /* Exclude channels */
724    FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0, 1);      /* excluded_chns_present*/
725
726    /* Multiband DRC */
727    FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0, 1);          /* drc_bands_present */
728    if (pMetadata->mpegDrc.drc_bands_present)
729    {
730      FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr, 4);                      /* drc_band_incr */
731      FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme, 4);           /* drc_interpolation_scheme */
732      drc_num_bands += pMetadata->mpegDrc.drc_band_incr;
733      for (i=0; i<drc_num_bands; i++) {
734        FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i], 8);                  /* drc_band_top */
735      }
736    }
737
738    /* Program Reference Level */
739    FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present, 1);               /* prog_ref_level_present */
740    if (pMetadata->mpegDrc.prog_ref_level_present)
741    {
742      FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level, 7);                     /* prog_ref_level */
743      FDKwriteBits(&bsWriter, prog_ref_lev_res_bits, 1);                                 /* prog_ref_level_reserved_bits */
744    }
745
746    /* DRC Values */
747    for (i=0; i<drc_num_bands; i++) {
748      FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0, 1);           /* dyn_rng_sgn[ */
749      FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i], 7);                     /* dyn_rng_ctl */
750    }
751
752    /* return number of valid bits in extension payload. */
753    return FDKgetValidBits(&bsWriter);
754}
755
756static INT WriteEtsiAncillaryDataPayload(
757        const AAC_METADATA* const pMetadata,
758        UCHAR* const              pExtensionPayload
759        )
760{
761    FDK_BITSTREAM bsWriter;
762    FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER);
763
764    /* ancillary_data_sync */
765    FDKwriteBits(&bsWriter, 0xBC, 8);
766
767    /* bs_info */
768    FDKwriteBits(&bsWriter, 0x3, 2);                                                     /* mpeg_audio_type */
769    FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode, 2);                            /* dolby_surround_mode */
770    FDKwriteBits(&bsWriter, 0x0, 4);                                                     /* reserved */
771
772    /* ancillary_data_status */
773    FDKwriteBits(&bsWriter, 0, 3);                                                       /* 3 bit Reserved, set to "0" */
774    FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0, 1);                          /* downmixing_levels_MPEG4_status */
775    FDKwriteBits(&bsWriter, 0, 1);                                                       /* Reserved, set to "0" */
776    FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0, 1);         /* audio_coding_mode_and_compression status */
777    FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0, 1); /* coarse_grain_timecode_status */
778    FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0, 1);   /* fine_grain_timecode_status */
779
780    /* downmixing_levels_MPEG4_status */
781    if (pMetadata->DmxLvl_On) {
782      FDKwriteBits(&bsWriter, encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel), 8);
783    }
784
785    /* audio_coding_mode_and_compression_status */
786    if (pMetadata->etsiAncData.compression_on) {
787      FDKwriteBits(&bsWriter, 0x01, 8);                                                  /* audio coding mode */
788      FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value, 8);              /* compression value */
789    }
790
791    /* grain-timecode coarse/fine */
792    if (pMetadata->etsiAncData.timecode_coarse_status) {
793      FDKwriteBits(&bsWriter, 0x0, 16);                                                  /* not yet supported */
794    }
795
796    if (pMetadata->etsiAncData.timecode_fine_status) {
797      FDKwriteBits(&bsWriter, 0x0, 16);                                                  /* not yet supported */
798    }
799
800    return FDKgetValidBits(&bsWriter);
801}
802
803
804static FDK_METADATA_ERROR LoadSubmittedMetadata(
805        const AACENC_MetaData * const   hMetadata,
806        const INT                       nChannels,
807        const INT                       metadataMode,
808        AAC_METADATA * const            pAacMetaData
809        )
810{
811    FDK_METADATA_ERROR err = METADATA_OK;
812
813    if (pAacMetaData==NULL) {
814      err = METADATA_INVALID_HANDLE;
815    }
816    else {
817      /* init struct */
818      FDKmemclear(pAacMetaData, sizeof(AAC_METADATA));
819
820      if (hMetadata!=NULL) {
821        /* convert data */
822        pAacMetaData->mpegDrc.drc_profile            = hMetadata->drc_profile;
823        pAacMetaData->etsiAncData.comp_profile       = hMetadata->comp_profile;
824        pAacMetaData->mpegDrc.drc_TargetRefLevel     = hMetadata->drc_TargetRefLevel;
825        pAacMetaData->etsiAncData.comp_TargetRefLevel= hMetadata->comp_TargetRefLevel;
826        pAacMetaData->mpegDrc.prog_ref_level_present = hMetadata->prog_ref_level_present;
827        pAacMetaData->mpegDrc.prog_ref_level         = dialnorm2progreflvl(hMetadata->prog_ref_level);
828
829        pAacMetaData->centerMixLevel                 = hMetadata->centerMixLevel;
830        pAacMetaData->surroundMixLevel               = hMetadata->surroundMixLevel;
831        pAacMetaData->WritePCEMixDwnIdx              = hMetadata->PCE_mixdown_idx_present;
832        pAacMetaData->DmxLvl_On                      = hMetadata->ETSI_DmxLvl_present;
833
834        pAacMetaData->etsiAncData.compression_on = 1;
835
836
837        if (nChannels == 2) {
838          pAacMetaData->dolbySurroundMode = hMetadata->dolbySurroundMode;     /* dolby_surround_mode */
839        } else {
840          pAacMetaData->dolbySurroundMode = 0;
841        }
842
843        pAacMetaData->etsiAncData.timecode_coarse_status = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */
844        pAacMetaData->etsiAncData.timecode_fine_status   = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */
845
846        pAacMetaData->metadataMode = metadataMode;
847      }
848      else {
849        pAacMetaData->metadataMode = 0;                      /* there is no configuration available */
850      }
851    }
852
853    return err;
854}
855
856INT FDK_MetadataEnc_GetDelay(
857        HANDLE_FDK_METADATA_ENCODER hMetadataEnc
858        )
859{
860    INT delay = 0;
861
862    if (hMetadataEnc!=NULL) {
863        delay = hMetadataEnc->nAudioDataDelay;
864    }
865
866    return delay;
867}
868
869
870