1/* -----------------------------------------------------------------------------
2Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4© Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5Forschung e.V. All rights reserved.
6
7 1.    INTRODUCTION
8The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10scheme for digital audio. This FDK AAC Codec software is intended to be used on
11a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14general perceptual audio codecs. AAC-ELD is considered the best-performing
15full-bandwidth communications codec by independent studies and is widely
16deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17specifications.
18
19Patent licenses for necessary patent claims for the FDK AAC Codec (including
20those of Fraunhofer) may be obtained through Via Licensing
21(www.vialicensing.com) or through the respective patent owners individually for
22the purpose of encoding or decoding bit streams in products that are compliant
23with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24Android devices already license these patent claims through Via Licensing or
25directly from the patent owners, and therefore FDK AAC Codec software may
26already be covered under those patent licenses when it is used for those
27licensed purposes only.
28
29Commercially-licensed AAC software libraries, including floating-point versions
30with enhanced sound quality, are also available from Fraunhofer. Users are
31encouraged to check the Fraunhofer website for additional applications
32information and documentation.
33
342.    COPYRIGHT LICENSE
35
36Redistribution and use in source and binary forms, with or without modification,
37are permitted without payment of copyright license fees provided that you
38satisfy the following conditions:
39
40You must retain the complete text of this software license in redistributions of
41the FDK AAC Codec or your modifications thereto in source code form.
42
43You must retain the complete text of this software license in the documentation
44and/or other materials provided with redistributions of the FDK AAC Codec or
45your modifications thereto in binary form. You must make available free of
46charge copies of the complete source code of the FDK AAC Codec and your
47modifications thereto to recipients of copies in binary form.
48
49The name of Fraunhofer may not be used to endorse or promote products derived
50from this library without prior written permission.
51
52You may not charge copyright license fees for anyone to use, copy or distribute
53the FDK AAC Codec software or your modifications thereto.
54
55Your modified versions of the FDK AAC Codec must carry prominent notices stating
56that you changed the software and the date of any change. For modified versions
57of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59AAC Codec Library for Android."
60
613.    NO PATENT LICENSE
62
63NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65Fraunhofer provides no warranty of patent non-infringement with respect to this
66software.
67
68You may use this FDK AAC Codec software or modifications thereto only for
69purposes that are authorized by appropriate patent licenses.
70
714.    DISCLAIMER
72
73This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75including but not limited to the implied warranties of merchantability and
76fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78or consequential damages, including but not limited to procurement of substitute
79goods or services; loss of use, data, or profits, or business interruption,
80however caused and on any theory of liability, whether in contract, strict
81liability, or tort (including negligence), arising in any way out of the use of
82this software, even if advised of the possibility of such damage.
83
845.    CONTACT INFORMATION
85
86Fraunhofer Institute for Integrated Circuits IIS
87Attention: Audio and Multimedia Departments - FDK AAC LL
88Am Wolfsmantel 33
8991058 Erlangen, Germany
90
91www.iis.fraunhofer.de/amm
92amm-info@iis.fraunhofer.de
93----------------------------------------------------------------------------- */
94
95/************************* MPEG-D DRC decoder library **************************
96
97   Author(s):
98
99   Description:
100
101*******************************************************************************/
102
103#include "drcDec_types.h"
104#include "drcDec_gainDecoder.h"
105#include "drcGainDec_preprocess.h"
106#include "drcGainDec_init.h"
107#include "drcGainDec_process.h"
108#include "drcDec_tools.h"
109
110/*******************************************/
111/* static functions                        */
112/*******************************************/
113
114static int _fitsLocation(DRC_INSTRUCTIONS_UNI_DRC* pInst,
115                         const GAIN_DEC_LOCATION drcLocation) {
116  int downmixId = pInst->drcApplyToDownmix ? pInst->downmixId[0] : 0;
117  switch (drcLocation) {
118    case GAIN_DEC_DRC1:
119      return (downmixId == 0);
120    case GAIN_DEC_DRC1_DRC2:
121      return ((downmixId == 0) || (downmixId == DOWNMIX_ID_ANY_DOWNMIX));
122    case GAIN_DEC_DRC2:
123      return (downmixId == DOWNMIX_ID_ANY_DOWNMIX);
124    case GAIN_DEC_DRC3:
125      return ((downmixId != 0) && (downmixId != DOWNMIX_ID_ANY_DOWNMIX));
126    case GAIN_DEC_DRC2_DRC3:
127      return (downmixId != 0);
128  }
129  return 0;
130}
131
132static void _setChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,
133                             const int numChannelGains,
134                             const FIXP_DBL* channelGainDb) {
135  int i, channelGain_e;
136  FIXP_DBL channelGain;
137  FDK_ASSERT(numChannelGains <= 8);
138  for (i = 0; i < numChannelGains; i++) {
139    if (channelGainDb[i] == (FIXP_DBL)MINVAL_DBL) {
140      hGainDec->channelGain[i] = (FIXP_DBL)0;
141    } else {
142      /* add loudness normalisation gain (dB) to channel gain (dB) */
143      FIXP_DBL tmp_channelGainDb = (channelGainDb[i] >> 1) +
144                                   (hGainDec->loudnessNormalisationGainDb >> 2);
145      tmp_channelGainDb =
146          SATURATE_LEFT_SHIFT(tmp_channelGainDb, 1, DFRACT_BITS);
147      channelGain = dB2lin(tmp_channelGainDb, 8, &channelGain_e);
148      hGainDec->channelGain[i] = scaleValue(channelGain, channelGain_e - 8);
149    }
150  }
151}
152
153/*******************************************/
154/* public functions                        */
155/*******************************************/
156
157DRC_ERROR
158drcDec_GainDecoder_Open(HANDLE_DRC_GAIN_DECODER* phGainDec) {
159  DRC_GAIN_DECODER* hGainDec = NULL;
160
161  hGainDec = (DRC_GAIN_DECODER*)FDKcalloc(1, sizeof(DRC_GAIN_DECODER));
162  if (hGainDec == NULL) return DE_MEMORY_ERROR;
163
164  hGainDec->multiBandActiveDrcIndex = -1;
165  hGainDec->channelGainActiveDrcIndex = -1;
166
167  *phGainDec = hGainDec;
168
169  return DE_OK;
170}
171
172DRC_ERROR
173drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
174                        const int sampleRate) {
175  DRC_ERROR err = DE_OK;
176
177  err = initGainDec(hGainDec, frameSize, sampleRate);
178  if (err) return err;
179
180  initDrcGainBuffers(hGainDec->frameSize, &hGainDec->drcGainBuffers);
181
182  return err;
183}
184
185DRC_ERROR
186drcDec_GainDecoder_SetCodecDependentParameters(
187    HANDLE_DRC_GAIN_DECODER hGainDec, const DELAY_MODE delayMode,
188    const int timeDomainSupported,
189    const SUBBAND_DOMAIN_MODE subbandDomainSupported) {
190  if ((delayMode != DM_REGULAR_DELAY) && (delayMode != DM_LOW_DELAY)) {
191    return DE_NOT_OK;
192  }
193  hGainDec->delayMode = delayMode;
194  hGainDec->timeDomainSupported = timeDomainSupported;
195  hGainDec->subbandDomainSupported = subbandDomainSupported;
196
197  return DE_OK;
198}
199
200DRC_ERROR
201drcDec_GainDecoder_Config(HANDLE_DRC_GAIN_DECODER hGainDec,
202                          HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
203                          const UCHAR numSelectedDrcSets,
204                          const SCHAR* selectedDrcSetIds,
205                          const UCHAR* selectedDownmixIds) {
206  DRC_ERROR err = DE_OK;
207  int a;
208
209  hGainDec->nActiveDrcs = 0;
210  hGainDec->multiBandActiveDrcIndex = -1;
211  hGainDec->channelGainActiveDrcIndex = -1;
212  for (a = 0; a < numSelectedDrcSets; a++) {
213    err = initActiveDrc(hGainDec, hUniDrcConfig, selectedDrcSetIds[a],
214                        selectedDownmixIds[a]);
215    if (err) return err;
216  }
217
218  err = initActiveDrcOffset(hGainDec);
219  if (err) return err;
220
221  return err;
222}
223
224DRC_ERROR
225drcDec_GainDecoder_Close(HANDLE_DRC_GAIN_DECODER* phGainDec) {
226  if (*phGainDec != NULL) {
227    FDKfree(*phGainDec);
228    *phGainDec = NULL;
229  }
230
231  return DE_OK;
232}
233
234DRC_ERROR
235drcDec_GainDecoder_Preprocess(HANDLE_DRC_GAIN_DECODER hGainDec,
236                              HANDLE_UNI_DRC_GAIN hUniDrcGain,
237                              const FIXP_DBL loudnessNormalizationGainDb,
238                              const FIXP_SGL boost, const FIXP_SGL compress) {
239  DRC_ERROR err = DE_OK;
240  int a, c;
241
242  /* lnbPointer is the index on the most recent node buffer */
243  hGainDec->drcGainBuffers.lnbPointer++;
244  if (hGainDec->drcGainBuffers.lnbPointer >= NUM_LNB_FRAMES)
245    hGainDec->drcGainBuffers.lnbPointer = 0;
246
247  for (a = 0; a < hGainDec->nActiveDrcs; a++) {
248    /* prepare gain interpolation of sequences used by copying and modifying
249     * nodes in node buffers */
250    err = prepareDrcGain(hGainDec, hUniDrcGain, compress, boost,
251                         loudnessNormalizationGainDb, a);
252    if (err) return err;
253  }
254
255  for (a = 0; a < MAX_ACTIVE_DRCS; a++) {
256    for (c = 0; c < 8; c++) {
257      hGainDec->activeDrc[a]
258          .lnbIndexForChannel[c][hGainDec->drcGainBuffers.lnbPointer] =
259          -1; /* "no DRC processing" */
260    }
261    hGainDec->activeDrc[a].subbandGainsReady = 0;
262  }
263
264  for (c = 0; c < 8; c++) {
265    hGainDec->drcGainBuffers
266        .channelGain[c][hGainDec->drcGainBuffers.lnbPointer] =
267        FL2FXCONST_DBL(1.0f / (float)(1 << 8));
268  }
269
270  return err;
271}
272
273/* create gain sequence out of gain sequences of last frame for concealment and
274 * flushing */
275DRC_ERROR
276drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec,
277                           HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
278                           HANDLE_UNI_DRC_GAIN hUniDrcGain) {
279  int seq, gainSequenceCount;
280  DRC_COEFFICIENTS_UNI_DRC* pCoef =
281      selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
282  if (pCoef == NULL) return DE_OK;
283
284  gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
285
286  for (seq = 0; seq < gainSequenceCount; seq++) {
287    int lastNodeIndex = 0;
288    FIXP_SGL lastGainDb = (FIXP_SGL)0;
289
290    lastNodeIndex = hUniDrcGain->nNodes[seq] - 1;
291    if ((lastNodeIndex >= 0) && (lastNodeIndex < 16)) {
292      lastGainDb = hUniDrcGain->gainNode[seq][lastNodeIndex].gainDb;
293    }
294
295    hUniDrcGain->nNodes[seq] = 1;
296    if (lastGainDb > (FIXP_SGL)0) {
297      hUniDrcGain->gainNode[seq][0].gainDb =
298          FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.9f), lastGainDb));
299    } else {
300      hUniDrcGain->gainNode[seq][0].gainDb =
301          FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.98f), lastGainDb));
302    }
303    hUniDrcGain->gainNode[seq][0].time = hGainDec->frameSize - 1;
304  }
305  return DE_OK;
306}
307
308void drcDec_GainDecoder_SetChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,
309                                        const int numChannels,
310                                        const int frameSize,
311                                        const FIXP_DBL* channelGainDb,
312                                        const int audioBufferChannelOffset,
313                                        FIXP_DBL* audioBuffer) {
314  int c, i;
315
316  if (hGainDec->channelGainActiveDrcIndex >= 0) {
317    /* channel gains will be applied in drcDec_GainDecoder_ProcessTimeDomain or
318     * drcDec_GainDecoder_ProcessSubbandDomain, respectively. */
319    _setChannelGains(hGainDec, numChannels, channelGainDb);
320
321    if (!hGainDec->status) { /* overwrite previous channel gains at startup */
322      DRC_GAIN_BUFFERS* pDrcGainBuffers = &hGainDec->drcGainBuffers;
323      for (c = 0; c < numChannels; c++) {
324        for (i = 0; i < NUM_LNB_FRAMES; i++) {
325          pDrcGainBuffers->channelGain[c][i] = hGainDec->channelGain[c];
326        }
327      }
328      hGainDec->status = 1;
329    }
330  } else {
331    /* smooth and apply channel gains */
332    FIXP_DBL prevChannelGain[8];
333    for (c = 0; c < numChannels; c++) {
334      prevChannelGain[c] = hGainDec->channelGain[c];
335    }
336
337    _setChannelGains(hGainDec, numChannels, channelGainDb);
338
339    if (!hGainDec->status) { /* overwrite previous channel gains at startup */
340      for (c = 0; c < numChannels; c++)
341        prevChannelGain[c] = hGainDec->channelGain[c];
342      hGainDec->status = 1;
343    }
344
345    for (c = 0; c < numChannels; c++) {
346      INT n_min = fMin(fMin(CntLeadingZeros(prevChannelGain[c]),
347                            CntLeadingZeros(hGainDec->channelGain[c])) -
348                           1,
349                       9);
350      FIXP_DBL gain = prevChannelGain[c] << n_min;
351      FIXP_DBL stepsize = ((hGainDec->channelGain[c] << n_min) - gain);
352      if (stepsize != (FIXP_DBL)0) {
353        if (frameSize == 1024)
354          stepsize = stepsize >> 10;
355        else
356          stepsize = (LONG)stepsize / frameSize;
357      }
358      n_min = 9 - n_min;
359#ifdef FUNCTION_drcDec_GainDecoder_SetChannelGains_func1
360      drcDec_GainDecoder_SetChannelGains_func1(audioBuffer, gain, stepsize,
361                                               n_min, frameSize);
362#else
363      for (i = 0; i < frameSize; i++) {
364        audioBuffer[i] = fMultDiv2(audioBuffer[i], gain) << n_min;
365        gain += stepsize;
366      }
367#endif
368      audioBuffer += audioBufferChannelOffset;
369    }
370  }
371}
372
373DRC_ERROR
374drcDec_GainDecoder_ProcessTimeDomain(
375    HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
376    const GAIN_DEC_LOCATION drcLocation, const int channelOffset,
377    const int drcChannelOffset, const int numChannelsProcessed,
378    const int timeDataChannelOffset, FIXP_DBL* audioIOBuffer) {
379  DRC_ERROR err = DE_OK;
380  int a;
381
382  if (!hGainDec->timeDomainSupported) {
383    return DE_NOT_OK;
384  }
385
386  for (a = 0; a < hGainDec->nActiveDrcs; a++) {
387    if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue;
388
389    /* Apply DRC */
390    err = processDrcTime(hGainDec, a, delaySamples, channelOffset,
391                         drcChannelOffset, numChannelsProcessed,
392                         timeDataChannelOffset, audioIOBuffer);
393    if (err) return err;
394  }
395
396  return err;
397}
398
399DRC_ERROR
400drcDec_GainDecoder_ProcessSubbandDomain(
401    HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
402    const GAIN_DEC_LOCATION drcLocation, const int channelOffset,
403    const int drcChannelOffset, const int numChannelsProcessed,
404    const int processSingleTimeslot, FIXP_DBL* audioIOBufferReal[],
405    FIXP_DBL* audioIOBufferImag[]) {
406  DRC_ERROR err = DE_OK;
407  int a;
408
409  if (hGainDec->subbandDomainSupported == SDM_OFF) {
410    return DE_NOT_OK;
411  }
412
413  for (a = 0; a < hGainDec->nActiveDrcs; a++) {
414    if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue;
415
416    /* Apply DRC */
417    err = processDrcSubband(hGainDec, a, delaySamples, channelOffset,
418                            drcChannelOffset, numChannelsProcessed,
419                            processSingleTimeslot, audioIOBufferReal,
420                            audioIOBufferImag);
421    if (err) return err;
422  }
423
424  return err;
425}
426
427DRC_ERROR
428drcDec_GainDecoder_SetLoudnessNormalizationGainDb(
429    HANDLE_DRC_GAIN_DECODER hGainDec, FIXP_DBL loudnessNormalizationGainDb) {
430  hGainDec->loudnessNormalisationGainDb = loudnessNormalizationGainDb;
431
432  return DE_OK;
433}
434
435int drcDec_GainDecoder_GetFrameSize(HANDLE_DRC_GAIN_DECODER hGainDec) {
436  if (hGainDec == NULL) return -1;
437
438  return hGainDec->frameSize;
439}
440
441int drcDec_GainDecoder_GetDeltaTminDefault(HANDLE_DRC_GAIN_DECODER hGainDec) {
442  if (hGainDec == NULL) return -1;
443
444  return hGainDec->deltaTminDefault;
445}
446