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 /*********************** MPEG surround encoder library *************************
96 
97    Author(s):   Josef Hoepfl
98 
99    Description: Encoder Library Interface
100                 vector functions
101 
102 *******************************************************************************/
103 
104 /*****************************************************************************
105 \file
106 This file contains vector functions
107 ******************************************************************************/
108 
109 /* Includes ******************************************************************/
110 #include "sacenc_vectorfunctions.h"
111 
112 /* Defines *******************************************************************/
113 
114 /* Data Types ****************************************************************/
115 
116 /* Constants *****************************************************************/
117 
118 /* Function / Class Declarations *********************************************/
119 
120 /* Function / Class Definition ***********************************************/
121 
sumUpCplxPow2(const FIXP_DPK * const x,const INT scaleMode,const INT inScaleFactor,INT * const outScaleFactor,const INT n)122 FIXP_DBL sumUpCplxPow2(const FIXP_DPK *const x, const INT scaleMode,
123                        const INT inScaleFactor, INT *const outScaleFactor,
124                        const INT n) {
125   int i, cs;
126 
127   if (scaleMode == SUM_UP_DYNAMIC_SCALE) {
128     /* calculate headroom */
129     FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
130     for (i = 0; i < n; i++) {
131       maxVal |= fAbs(x[i].v.re);
132       maxVal |= fAbs(x[i].v.im);
133     }
134     cs = inScaleFactor - fixMax(0, CntLeadingZeros(maxVal) - 1);
135   } else {
136     cs = inScaleFactor;
137   }
138 
139   /* consider scaling of energy and scaling in fPow2Div2 and addition */
140   *outScaleFactor = 2 * cs + 2;
141 
142   /* make sure that the scalefactor is in the range of -(DFRACT_BITS-1), ... ,
143    * (DFRACT_BITS-1) */
144   cs = fixMax(fixMin(cs, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
145 
146   /* sum up complex energy samples */
147   FIXP_DBL re, im, sum;
148 
149   re = im = sum = FL2FXCONST_DBL(0.0);
150   if (cs < 0) {
151     cs = -cs;
152     for (i = 0; i < n; i++) {
153       re += fPow2Div2(x[i].v.re << cs);
154       im += fPow2Div2(x[i].v.im << cs);
155     }
156   } else {
157     cs = 2 * cs;
158     for (i = 0; i < n; i++) {
159       re += fPow2Div2(x[i].v.re) >> cs;
160       im += fPow2Div2(x[i].v.im) >> cs;
161     }
162   }
163 
164   sum = (re >> 1) + (im >> 1);
165 
166   return (sum);
167 }
168 
sumUpCplxPow2Dim2(const FIXP_DPK * const * const x,const INT scaleMode,const INT inScaleFactor,INT * const outScaleFactor,const INT sDim1,const INT nDim1,const INT sDim2,const INT nDim2)169 FIXP_DBL sumUpCplxPow2Dim2(const FIXP_DPK *const *const x, const INT scaleMode,
170                            const INT inScaleFactor, INT *const outScaleFactor,
171                            const INT sDim1, const INT nDim1, const INT sDim2,
172                            const INT nDim2) {
173   int i, j, cs;
174 
175   if (scaleMode == SUM_UP_DYNAMIC_SCALE) {
176     /* calculate headroom */
177     FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
178     for (i = sDim1; i < nDim1; i++) {
179       for (j = sDim2; j < nDim2; j++) {
180         maxVal |= fAbs(x[i][j].v.re);
181         maxVal |= fAbs(x[i][j].v.im);
182       }
183     }
184     cs = inScaleFactor - fixMax(0, CntLeadingZeros(maxVal) - 1);
185   } else {
186     cs = inScaleFactor;
187   }
188 
189   /* consider scaling of energy and scaling in fPow2Div2 and addition */
190   *outScaleFactor = 2 * cs + 2;
191 
192   /* make sure that the scalefactor is in the range of -(DFRACT_BITS-1), ... ,
193    * (DFRACT_BITS-1) */
194   cs = fixMax(fixMin(cs, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
195 
196   /* sum up complex energy samples */
197   FIXP_DBL re, im, sum;
198 
199   re = im = sum = FL2FXCONST_DBL(0.0);
200   if (cs < 0) {
201     cs = -cs;
202     for (i = sDim1; i < nDim1; i++) {
203       for (j = sDim2; j < nDim2; j++) {
204         re += fPow2Div2(x[i][j].v.re << cs);
205         im += fPow2Div2(x[i][j].v.im << cs);
206       }
207     }
208   } else {
209     cs = 2 * cs;
210     for (i = sDim1; i < nDim1; i++) {
211       for (j = sDim2; j < nDim2; j++) {
212         re += fPow2Div2(x[i][j].v.re) >> cs;
213         im += fPow2Div2(x[i][j].v.im) >> cs;
214       }
215     }
216   }
217 
218   sum = (re >> 1) + (im >> 1);
219 
220   return (sum);
221 }
222 
copyCplxVec(FIXP_DPK * const Z,const FIXP_DPK * const X,const INT n)223 void copyCplxVec(FIXP_DPK *const Z, const FIXP_DPK *const X, const INT n) {
224   FDKmemmove(Z, X, sizeof(FIXP_DPK) * n);
225 }
226 
setCplxVec(FIXP_DPK * const Z,const FIXP_DBL a,const INT n)227 void setCplxVec(FIXP_DPK *const Z, const FIXP_DBL a, const INT n) {
228   int i;
229 
230   for (i = 0; i < n; i++) {
231     Z[i].v.re = a;
232     Z[i].v.im = a;
233   }
234 }
235 
cplx_cplxScalarProduct(FIXP_DPK * const Z,const FIXP_DPK * const * const X,const FIXP_DPK * const * const Y,const INT scaleX,const INT scaleY,INT * const scaleZ,const INT sDim1,const INT nDim1,const INT sDim2,const INT nDim2)236 void cplx_cplxScalarProduct(FIXP_DPK *const Z, const FIXP_DPK *const *const X,
237                             const FIXP_DPK *const *const Y, const INT scaleX,
238                             const INT scaleY, INT *const scaleZ,
239                             const INT sDim1, const INT nDim1, const INT sDim2,
240                             const INT nDim2) {
241   int i, j, sx, sy;
242   FIXP_DBL xre, yre, xim, yim, re, im;
243 
244   /* make sure that the scalefactor is in the range of -(DFRACT_BITS-1), ... ,
245    * (DFRACT_BITS-1) */
246   sx = fixMax(fixMin(scaleX, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
247   sy = fixMax(fixMin(scaleY, DFRACT_BITS - 1), -(DFRACT_BITS - 1));
248 
249   /* consider scaling of energy and scaling in fMultDiv2 and shift of result
250    * values */
251   *scaleZ = sx + sy + 2;
252 
253   re = (FIXP_DBL)0;
254   im = (FIXP_DBL)0;
255   if ((sx < 0) && (sy < 0)) {
256     sx = -sx;
257     sy = -sy;
258     for (i = sDim1; i < nDim1; i++) {
259       for (j = sDim2; j < nDim2; j++) {
260         xre = X[i][j].v.re << sx;
261         xim = X[i][j].v.im << sx;
262         yre = Y[i][j].v.re << sy;
263         yim = Y[i][j].v.im << sy;
264         re += fMultDiv2(xre, yre) + fMultDiv2(xim, yim);
265         im += fMultDiv2(xim, yre) - fMultDiv2(xre, yim);
266       }
267     }
268   } else if ((sx >= 0) && (sy >= 0)) {
269     for (i = sDim1; i < nDim1; i++) {
270       for (j = sDim2; j < nDim2; j++) {
271         xre = X[i][j].v.re;
272         xim = X[i][j].v.im;
273         yre = Y[i][j].v.re;
274         yim = Y[i][j].v.im;
275         re += (fMultDiv2(xre, yre) + fMultDiv2(xim, yim)) >> (sx + sy);
276         im += (fMultDiv2(xim, yre) - fMultDiv2(xre, yim)) >> (sx + sy);
277       }
278     }
279   } else if ((sx < 0) && (sy >= 0)) {
280     sx = -sx;
281     for (i = sDim1; i < nDim1; i++) {
282       for (j = sDim2; j < nDim2; j++) {
283         xre = X[i][j].v.re << sx;
284         xim = X[i][j].v.im << sx;
285         yre = Y[i][j].v.re;
286         yim = Y[i][j].v.im;
287         re += (fMultDiv2(xre, yre) + fMultDiv2(xim, yim)) >> sy;
288         im += (fMultDiv2(xim, yre) - fMultDiv2(xre, yim)) >> sy;
289       }
290     }
291   } else {
292     sy = -sy;
293     for (i = sDim1; i < nDim1; i++) {
294       for (j = sDim2; j < nDim2; j++) {
295         xre = X[i][j].v.re;
296         xim = X[i][j].v.im;
297         yre = Y[i][j].v.re << sy;
298         yim = Y[i][j].v.im << sy;
299         re += (fMultDiv2(xre, yre) + fMultDiv2(xim, yim)) >> sx;
300         im += (fMultDiv2(xim, yre) - fMultDiv2(xre, yim)) >> sx;
301       }
302     }
303   }
304 
305   Z->v.re = re >> 1;
306   Z->v.im = im >> 1;
307 }
308 
FDKcalcCorrelationVec(FIXP_DBL * const z,const FIXP_DBL * const pr12,const FIXP_DBL * const p1,const FIXP_DBL * const p2,const INT n)309 void FDKcalcCorrelationVec(FIXP_DBL *const z, const FIXP_DBL *const pr12,
310                            const FIXP_DBL *const p1, const FIXP_DBL *const p2,
311                            const INT n) {
312   int i, s;
313   FIXP_DBL p12, cor;
314 
315   /* correlation */
316   for (i = 0; i < n; i++) {
317     p12 = fMult(p1[i], p2[i]);
318     if (p12 > FL2FXCONST_DBL(0.0f)) {
319       p12 = invSqrtNorm2(p12, &s);
320       cor = fMult(pr12[i], p12);
321       z[i] = SATURATE_LEFT_SHIFT(cor, s, DFRACT_BITS);
322     } else {
323       z[i] = (FIXP_DBL)MAXVAL_DBL;
324     }
325   }
326 }
327 
calcCoherenceVec(FIXP_DBL * const z,const FIXP_DBL * const p12r,const FIXP_DBL * const p12i,const FIXP_DBL * const p1,const FIXP_DBL * const p2,const INT scaleP12,const INT scaleP,const INT n)328 void calcCoherenceVec(FIXP_DBL *const z, const FIXP_DBL *const p12r,
329                       const FIXP_DBL *const p12i, const FIXP_DBL *const p1,
330                       const FIXP_DBL *const p2, const INT scaleP12,
331                       const INT scaleP, const INT n) {
332   int i, s, s1, s2;
333   FIXP_DBL coh, p12, p12ri;
334 
335   for (i = 0; i < n; i++) {
336     s2 = fixMin(fixMax(0, CountLeadingBits(p12r[i]) - 1),
337                 fixMax(0, CountLeadingBits(p12i[i]) - 1));
338     p12ri = sqrtFixp(fPow2Div2(p12r[i] << s2) + fPow2Div2(p12i[i] << s2));
339     s1 = fixMin(fixMax(0, CountLeadingBits(p1[i]) - 1),
340                 fixMax(0, CountLeadingBits(p2[i]) - 1));
341     p12 = fMultDiv2(p1[i] << s1, p2[i] << s1);
342 
343     if (p12 > FL2FXCONST_DBL(0.0f)) {
344       p12 = invSqrtNorm2(p12, &s);
345       coh = fMult(p12ri, p12);
346       s = fixMax(fixMin((scaleP12 - scaleP + s + s1 - s2), DFRACT_BITS - 1),
347                  -(DFRACT_BITS - 1));
348       if (s < 0) {
349         z[i] = coh >> (-s);
350       } else {
351         z[i] = SATURATE_LEFT_SHIFT(coh, s, DFRACT_BITS);
352       }
353     } else {
354       z[i] = (FIXP_DBL)MAXVAL_DBL;
355     }
356   }
357 }
358 
addWeightedCplxVec(FIXP_DPK * const * const Z,const FIXP_DBL * const a,const FIXP_DPK * const * const X,const FIXP_DBL * const b,const FIXP_DPK * const * const Y,const INT scale,INT * const scaleCh1,const INT scaleCh2,const UCHAR * const pParameterBand2HybridBandOffset,const INT nParameterBands,const INT nTimeSlots,const INT startTimeSlot)359 void addWeightedCplxVec(FIXP_DPK *const *const Z, const FIXP_DBL *const a,
360                         const FIXP_DPK *const *const X, const FIXP_DBL *const b,
361                         const FIXP_DPK *const *const Y, const INT scale,
362                         INT *const scaleCh1, const INT scaleCh2,
363                         const UCHAR *const pParameterBand2HybridBandOffset,
364                         const INT nParameterBands, const INT nTimeSlots,
365                         const INT startTimeSlot) {
366   int pb, j, i;
367   int cs, s1, s2;
368 
369   /* determine maximum scale of both channels */
370   cs = fixMax(*scaleCh1, scaleCh2);
371   s1 = cs - (*scaleCh1);
372   s2 = cs - scaleCh2;
373 
374   /* scalefactor 1 is updated with common scale of channel 1 and channel2 */
375   *scaleCh1 = cs;
376 
377   /* scale of a and b; additional scale for fMultDiv2() */
378   for (j = 0, pb = 0; pb < nParameterBands; pb++) {
379     FIXP_DBL aPb, bPb;
380     aPb = a[pb], bPb = b[pb];
381     for (; j < pParameterBand2HybridBandOffset[pb]; j++) {
382       for (i = startTimeSlot; i < nTimeSlots; i++) {
383         Z[j][i].v.re = ((fMultDiv2(aPb, X[j][i].v.re) >> s1) +
384                         (fMultDiv2(bPb, Y[j][i].v.re) >> s2))
385                        << (scale + 1);
386         Z[j][i].v.im = ((fMultDiv2(aPb, X[j][i].v.im) >> s1) +
387                         (fMultDiv2(bPb, Y[j][i].v.im) >> s2))
388                        << (scale + 1);
389       }
390     }
391   }
392 }
393 
FDKcalcPbScaleFactor(const FIXP_DPK * const * const x,const UCHAR * const pParameterBand2HybridBandOffset,INT * const outScaleFactor,const INT startTimeSlot,const INT nTimeSlots,const INT nParamBands)394 void FDKcalcPbScaleFactor(const FIXP_DPK *const *const x,
395                           const UCHAR *const pParameterBand2HybridBandOffset,
396                           INT *const outScaleFactor, const INT startTimeSlot,
397                           const INT nTimeSlots, const INT nParamBands) {
398   int i, j, pb;
399 
400   /* calculate headroom */
401   for (j = 0, pb = 0; pb < nParamBands; pb++) {
402     FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
403     for (; j < pParameterBand2HybridBandOffset[pb]; j++) {
404       for (i = startTimeSlot; i < nTimeSlots; i++) {
405         maxVal |= fAbs(x[i][j].v.re);
406         maxVal |= fAbs(x[i][j].v.im);
407       }
408     }
409     outScaleFactor[pb] = -fixMax(0, CntLeadingZeros(maxVal) - 1);
410   }
411 }
412 
FDKcalcScaleFactor(const FIXP_DBL * const x,const FIXP_DBL * const y,const INT n)413 INT FDKcalcScaleFactor(const FIXP_DBL *const x, const FIXP_DBL *const y,
414                        const INT n) {
415   int i;
416 
417   /* calculate headroom */
418   FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
419   if (x != NULL) {
420     for (i = 0; i < n; i++) {
421       maxVal |= fAbs(x[i]);
422     }
423   }
424 
425   if (y != NULL) {
426     for (i = 0; i < n; i++) {
427       maxVal |= fAbs(y[i]);
428     }
429   }
430 
431   if (maxVal == (FIXP_DBL)0)
432     return (-(DFRACT_BITS - 1));
433   else
434     return (-CountLeadingBits(maxVal));
435 }
436 
FDKcalcScaleFactorDPK(const FIXP_DPK * RESTRICT x,const INT startBand,const INT bands)437 INT FDKcalcScaleFactorDPK(const FIXP_DPK *RESTRICT x, const INT startBand,
438                           const INT bands) {
439   INT qs, clz;
440   FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f);
441 
442   for (qs = startBand; qs < bands; qs++) {
443     maxVal |= fAbs(x[qs].v.re);
444     maxVal |= fAbs(x[qs].v.im);
445   }
446 
447   clz = -fixMax(0, CntLeadingZeros(maxVal) - 1);
448 
449   return (clz);
450 }
451