• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6 
7  1.    INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18 
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28 
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33 
34 2.    COPYRIGHT LICENSE
35 
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39 
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42 
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48 
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51 
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54 
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60 
61 3.    NO PATENT LICENSE
62 
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67 
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70 
71 4.    DISCLAIMER
72 
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83 
84 5.    CONTACT INFORMATION
85 
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90 
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94 
95 /**************************** AAC encoder library ******************************
96 
97    Author(s):   M. Werner
98 
99    Description: Band/Line energy calculations
100 
101 *******************************************************************************/
102 
103 #include "band_nrg.h"
104 
105 /*****************************************************************************
106   functionname: FDKaacEnc_CalcSfbMaxScaleSpec
107   description:
108   input:
109   output:
110 *****************************************************************************/
FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL * RESTRICT mdctSpectrum,const INT * RESTRICT bandOffset,INT * RESTRICT sfbMaxScaleSpec,const INT numBands)111 void FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *RESTRICT mdctSpectrum,
112                                    const INT *RESTRICT bandOffset,
113                                    INT *RESTRICT sfbMaxScaleSpec,
114                                    const INT numBands) {
115   INT i, j;
116   FIXP_DBL maxSpc, tmp;
117 
118   for (i = 0; i < numBands; i++) {
119     maxSpc = (FIXP_DBL)0;
120 
121     DWORD_ALIGNED(mdctSpectrum);
122 
123     for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
124       tmp = fixp_abs(mdctSpectrum[j]);
125       maxSpc = fixMax(maxSpc, tmp);
126     }
127     j = CntLeadingZeros(maxSpc) - 1;
128     sfbMaxScaleSpec[i] = fixMin((DFRACT_BITS - 2), j);
129     /* CountLeadingBits() is not necessary here since test value is always > 0
130      */
131   }
132 }
133 
134 /*****************************************************************************
135   functionname: FDKaacEnc_CheckBandEnergyOptim
136   description:
137   input:
138   output:
139 *****************************************************************************/
140 FIXP_DBL
FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL * const RESTRICT mdctSpectrum,const INT * const RESTRICT sfbMaxScaleSpec,const INT * const RESTRICT bandOffset,const INT numBands,FIXP_DBL * RESTRICT bandEnergy,FIXP_DBL * RESTRICT bandEnergyLdData,const INT minSpecShift)141 FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *const RESTRICT mdctSpectrum,
142                                const INT *const RESTRICT sfbMaxScaleSpec,
143                                const INT *const RESTRICT bandOffset,
144                                const INT numBands,
145                                FIXP_DBL *RESTRICT bandEnergy,
146                                FIXP_DBL *RESTRICT bandEnergyLdData,
147                                const INT minSpecShift) {
148   INT i, j, scale, nr = 0;
149   FIXP_DBL maxNrgLd = FL2FXCONST_DBL(-1.0f);
150   FIXP_DBL maxNrg = 0;
151   FIXP_DBL spec;
152 
153   for (i = 0; i < numBands; i++) {
154     scale = fixMax(0, sfbMaxScaleSpec[i] - 4);
155     FIXP_DBL tmp = 0;
156 
157     DWORD_ALIGNED(mdctSpectrum);
158 
159     for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
160       spec = mdctSpectrum[j] << scale;
161       tmp = fPow2AddDiv2(tmp, spec);
162     }
163     bandEnergy[i] = tmp << 1;
164 
165     /* calculate ld of bandNrg, subtract scaling */
166     bandEnergyLdData[i] = CalcLdData(bandEnergy[i]);
167     if (bandEnergyLdData[i] != FL2FXCONST_DBL(-1.0f)) {
168       bandEnergyLdData[i] -= scale * FL2FXCONST_DBL(2.0 / 64);
169     }
170     /* find index of maxNrg */
171     if (bandEnergyLdData[i] > maxNrgLd) {
172       maxNrgLd = bandEnergyLdData[i];
173       nr = i;
174     }
175   }
176 
177   /* return unscaled maxNrg*/
178   scale = fixMax(0, sfbMaxScaleSpec[nr] - 4);
179   scale = fixMax(2 * (minSpecShift - scale), -(DFRACT_BITS - 1));
180 
181   maxNrg = scaleValue(bandEnergy[nr], scale);
182 
183   return maxNrg;
184 }
185 
186 /*****************************************************************************
187   functionname: FDKaacEnc_CalcBandEnergyOptimLong
188   description:
189   input:
190   output:
191 *****************************************************************************/
FDKaacEnc_CalcBandEnergyOptimLong(const FIXP_DBL * RESTRICT mdctSpectrum,INT * RESTRICT sfbMaxScaleSpec,const INT * RESTRICT bandOffset,const INT numBands,FIXP_DBL * RESTRICT bandEnergy,FIXP_DBL * RESTRICT bandEnergyLdData)192 INT FDKaacEnc_CalcBandEnergyOptimLong(const FIXP_DBL *RESTRICT mdctSpectrum,
193                                       INT *RESTRICT sfbMaxScaleSpec,
194                                       const INT *RESTRICT bandOffset,
195                                       const INT numBands,
196                                       FIXP_DBL *RESTRICT bandEnergy,
197                                       FIXP_DBL *RESTRICT bandEnergyLdData) {
198   INT i, j, shiftBits = 0;
199   FIXP_DBL maxNrgLd = FL2FXCONST_DBL(0.0f);
200 
201   FIXP_DBL spec;
202 
203   for (i = 0; i < numBands; i++) {
204     INT leadingBits = sfbMaxScaleSpec[i] -
205                       4; /* max sfbWidth = 96 ; 2^7=128 => 7/2 = 4 (spc*spc) */
206     FIXP_DBL tmp = FL2FXCONST_DBL(0.0);
207     /* don't use scaleValue() here, it increases workload quite sufficiently...
208      */
209     if (leadingBits >= 0) {
210       for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
211         spec = mdctSpectrum[j] << leadingBits;
212         tmp = fPow2AddDiv2(tmp, spec);
213       }
214     } else {
215       INT shift = -leadingBits;
216       for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
217         spec = mdctSpectrum[j] >> shift;
218         tmp = fPow2AddDiv2(tmp, spec);
219       }
220     }
221     bandEnergy[i] = tmp << 1;
222   }
223 
224   /* calculate ld of bandNrg, subtract scaling */
225   LdDataVector(bandEnergy, bandEnergyLdData, numBands);
226   for (i = numBands; i-- != 0;) {
227     FIXP_DBL scaleDiff = (sfbMaxScaleSpec[i] - 4) * FL2FXCONST_DBL(2.0 / 64);
228 
229     bandEnergyLdData[i] = (bandEnergyLdData[i] >=
230                            ((FL2FXCONST_DBL(-1.f) >> 1) + (scaleDiff >> 1)))
231                               ? bandEnergyLdData[i] - scaleDiff
232                               : FL2FXCONST_DBL(-1.f);
233     /* find maxNrgLd */
234     maxNrgLd = fixMax(maxNrgLd, bandEnergyLdData[i]);
235   }
236 
237   if (maxNrgLd <= (FIXP_DBL)0) {
238     for (i = numBands; i-- != 0;) {
239       INT scale = fixMin((sfbMaxScaleSpec[i] - 4) << 1, (DFRACT_BITS - 1));
240       bandEnergy[i] = scaleValue(bandEnergy[i], -scale);
241     }
242     return 0;
243   } else { /* scale down NRGs */
244     while (maxNrgLd > FL2FXCONST_DBL(0.0f)) {
245       maxNrgLd -= FL2FXCONST_DBL(2.0 / 64);
246       shiftBits++;
247     }
248     for (i = numBands; i-- != 0;) {
249       INT scale = fixMin(((sfbMaxScaleSpec[i] - 4) + shiftBits) << 1,
250                          (DFRACT_BITS - 1));
251       bandEnergyLdData[i] -= shiftBits * FL2FXCONST_DBL(2.0 / 64);
252       bandEnergy[i] = scaleValue(bandEnergy[i], -scale);
253     }
254     return shiftBits;
255   }
256 }
257 
258 /*****************************************************************************
259   functionname: FDKaacEnc_CalcBandEnergyOptimShort
260   description:
261   input:
262   output:
263 *****************************************************************************/
FDKaacEnc_CalcBandEnergyOptimShort(const FIXP_DBL * RESTRICT mdctSpectrum,INT * RESTRICT sfbMaxScaleSpec,const INT * RESTRICT bandOffset,const INT numBands,FIXP_DBL * RESTRICT bandEnergy)264 void FDKaacEnc_CalcBandEnergyOptimShort(const FIXP_DBL *RESTRICT mdctSpectrum,
265                                         INT *RESTRICT sfbMaxScaleSpec,
266                                         const INT *RESTRICT bandOffset,
267                                         const INT numBands,
268                                         FIXP_DBL *RESTRICT bandEnergy) {
269   INT i, j;
270 
271   for (i = 0; i < numBands; i++) {
272     int leadingBits = sfbMaxScaleSpec[i] -
273                       3; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */
274     FIXP_DBL tmp = FL2FXCONST_DBL(0.0);
275     for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
276       FIXP_DBL spec = scaleValue(mdctSpectrum[j], leadingBits);
277       tmp = fPow2AddDiv2(tmp, spec);
278     }
279     bandEnergy[i] = tmp;
280   }
281 
282   for (i = 0; i < numBands; i++) {
283     INT scale = (2 * (sfbMaxScaleSpec[i] - 3)) -
284                 1; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */
285     scale = fixMax(fixMin(scale, (DFRACT_BITS - 1)), -(DFRACT_BITS - 1));
286     bandEnergy[i] = scaleValueSaturate(bandEnergy[i], -scale);
287   }
288 }
289 
290 /*****************************************************************************
291   functionname: FDKaacEnc_CalcBandNrgMSOpt
292   description:
293   input:
294   output:
295 *****************************************************************************/
FDKaacEnc_CalcBandNrgMSOpt(const FIXP_DBL * RESTRICT mdctSpectrumLeft,const FIXP_DBL * RESTRICT mdctSpectrumRight,INT * RESTRICT sfbMaxScaleSpecLeft,INT * RESTRICT sfbMaxScaleSpecRight,const INT * RESTRICT bandOffset,const INT numBands,FIXP_DBL * RESTRICT bandEnergyMid,FIXP_DBL * RESTRICT bandEnergySide,INT calcLdData,FIXP_DBL * RESTRICT bandEnergyMidLdData,FIXP_DBL * RESTRICT bandEnergySideLdData)296 void FDKaacEnc_CalcBandNrgMSOpt(
297     const FIXP_DBL *RESTRICT mdctSpectrumLeft,
298     const FIXP_DBL *RESTRICT mdctSpectrumRight,
299     INT *RESTRICT sfbMaxScaleSpecLeft, INT *RESTRICT sfbMaxScaleSpecRight,
300     const INT *RESTRICT bandOffset, const INT numBands,
301     FIXP_DBL *RESTRICT bandEnergyMid, FIXP_DBL *RESTRICT bandEnergySide,
302     INT calcLdData, FIXP_DBL *RESTRICT bandEnergyMidLdData,
303     FIXP_DBL *RESTRICT bandEnergySideLdData) {
304   INT i, j, minScale;
305   FIXP_DBL NrgMid, NrgSide, specm, specs;
306 
307   for (i = 0; i < numBands; i++) {
308     NrgMid = NrgSide = FL2FXCONST_DBL(0.0);
309     minScale = fixMin(sfbMaxScaleSpecLeft[i], sfbMaxScaleSpecRight[i]) - 4;
310     minScale = fixMax(0, minScale);
311 
312     if (minScale > 0) {
313       for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
314         FIXP_DBL specL = mdctSpectrumLeft[j] << (minScale - 1);
315         FIXP_DBL specR = mdctSpectrumRight[j] << (minScale - 1);
316         specm = specL + specR;
317         specs = specL - specR;
318         NrgMid = fPow2AddDiv2(NrgMid, specm);
319         NrgSide = fPow2AddDiv2(NrgSide, specs);
320       }
321     } else {
322       for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) {
323         FIXP_DBL specL = mdctSpectrumLeft[j] >> 1;
324         FIXP_DBL specR = mdctSpectrumRight[j] >> 1;
325         specm = specL + specR;
326         specs = specL - specR;
327         NrgMid = fPow2AddDiv2(NrgMid, specm);
328         NrgSide = fPow2AddDiv2(NrgSide, specs);
329       }
330     }
331     bandEnergyMid[i] = fMin(NrgMid, (FIXP_DBL)MAXVAL_DBL >> 1) << 1;
332     bandEnergySide[i] = fMin(NrgSide, (FIXP_DBL)MAXVAL_DBL >> 1) << 1;
333   }
334 
335   if (calcLdData) {
336     LdDataVector(bandEnergyMid, bandEnergyMidLdData, numBands);
337     LdDataVector(bandEnergySide, bandEnergySideLdData, numBands);
338   }
339 
340   for (i = 0; i < numBands; i++) {
341     minScale = fixMin(sfbMaxScaleSpecLeft[i], sfbMaxScaleSpecRight[i]);
342     INT scale = fixMax(0, 2 * (minScale - 4));
343 
344     if (calcLdData) {
345       /* using the minimal scaling of left and right channel can cause very
346       small energies; check ldNrg before subtract scaling multiplication:
347       fract*INT we don't need fMult */
348 
349       int minus = scale * FL2FXCONST_DBL(1.0 / 64);
350 
351       if (bandEnergyMidLdData[i] != FL2FXCONST_DBL(-1.0f))
352         bandEnergyMidLdData[i] -= minus;
353 
354       if (bandEnergySideLdData[i] != FL2FXCONST_DBL(-1.0f))
355         bandEnergySideLdData[i] -= minus;
356     }
357     scale = fixMin(scale, (DFRACT_BITS - 1));
358     bandEnergyMid[i] >>= scale;
359     bandEnergySide[i] >>= scale;
360   }
361 }
362