1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5� Copyright  1995 - 2015 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/******************************** MPEG Audio Encoder **************************
85
86   Initial author:       M.Werner
87   contents/description: Quantization
88
89******************************************************************************/
90
91#include "quantize.h"
92
93#include "aacEnc_rom.h"
94
95/*****************************************************************************
96
97    functionname: FDKaacEnc_quantizeLines
98    description: quantizes spectrum lines
99    returns:
100    input: global gain, number of lines to process, spectral data
101    output: quantized spectrum
102
103*****************************************************************************/
104static void FDKaacEnc_quantizeLines(INT      gain,
105                          INT      noOfLines,
106                          FIXP_DBL *mdctSpectrum,
107                          SHORT    *quaSpectrum,
108                          INT      dZoneQuantEnable)
109{
110  int   line;
111  FIXP_DBL k = FL2FXCONST_DBL(0.0f);
112  FIXP_QTD quantizer = FDKaacEnc_quantTableQ[(-gain)&3];
113  INT      quantizershift = ((-gain)>>2)+1;
114  const INT kShift=16;
115
116  if (dZoneQuantEnable)
117    k = FL2FXCONST_DBL(0.23f)>>kShift;
118  else
119    k = FL2FXCONST_DBL(-0.0946f + 0.5f)>>kShift;
120
121  for (line = 0; line < noOfLines; line++)
122  {
123    FIXP_DBL accu = fMultDiv2(mdctSpectrum[line],quantizer);
124
125    if (accu < FL2FXCONST_DBL(0.0f))
126    {
127      accu=-accu;
128      /* normalize */
129      INT   accuShift = CntLeadingZeros(accu) - 1;  /* CountLeadingBits() is not necessary here since test value is always > 0 */
130      accu <<= accuShift;
131      INT tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE);
132      INT totalShift = quantizershift-accuShift+1;
133      accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],FDKaacEnc_quantTableE[totalShift&3]);
134      totalShift = (16-4)-(3*(totalShift>>2));
135      FDK_ASSERT(totalShift >=0); /* MAX_QUANT_VIOLATION */
136      accu >>= fixMin(totalShift,DFRACT_BITS-1);
137      quaSpectrum[line] = (SHORT)(-((LONG)(k + accu) >> (DFRACT_BITS-1-16)));
138    }
139    else if(accu > FL2FXCONST_DBL(0.0f))
140    {
141      /* normalize */
142      INT   accuShift = CntLeadingZeros(accu) - 1;  /* CountLeadingBits() is not necessary here since test value is always > 0 */
143      accu <<= accuShift;
144      INT tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE);
145      INT totalShift = quantizershift-accuShift+1;
146      accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],FDKaacEnc_quantTableE[totalShift&3]);
147      totalShift = (16-4)-(3*(totalShift>>2));
148      FDK_ASSERT(totalShift >=0); /* MAX_QUANT_VIOLATION */
149      accu >>= fixMin(totalShift,DFRACT_BITS-1);
150      quaSpectrum[line] = (SHORT)((LONG)(k + accu) >> (DFRACT_BITS-1-16));
151    }
152    else
153      quaSpectrum[line]=0;
154  }
155}
156
157
158/*****************************************************************************
159
160    functionname:iFDKaacEnc_quantizeLines
161    description: iquantizes spectrum lines
162                 mdctSpectrum = iquaSpectrum^4/3 *2^(0.25*gain)
163    input: global gain, number of lines to process,quantized spectrum
164    output: spectral data
165
166*****************************************************************************/
167static void FDKaacEnc_invQuantizeLines(INT  gain,
168                             INT  noOfLines,
169                             SHORT *quantSpectrum,
170                             FIXP_DBL *mdctSpectrum)
171
172{
173  INT iquantizermod;
174  INT iquantizershift;
175  INT line;
176
177  iquantizermod = gain&3;
178  iquantizershift = gain>>2;
179
180  for (line = 0; line < noOfLines; line++) {
181
182    if(quantSpectrum[line] < 0) {
183      FIXP_DBL accu;
184      INT ex,specExp,tabIndex;
185      FIXP_DBL s,t;
186
187      accu = (FIXP_DBL) -quantSpectrum[line];
188
189      ex = CountLeadingBits(accu);
190      accu <<= ex;
191      specExp = (DFRACT_BITS-1) - ex;
192
193      FDK_ASSERT(specExp < 14);       /* this fails if abs(value) > 8191 */
194
195      tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE);
196
197      /* calculate "mantissa" ^4/3 */
198      s = FDKaacEnc_mTab_4_3Elc[tabIndex];
199
200      /* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */
201      t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp];
202
203      /* multiply "mantissa" ^4/3 with exponent multiplier */
204      accu = fMult(s,t);
205
206      /* get approperiate exponent shifter */
207      specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp]-1; /* -1 to avoid overflows in accu */
208
209      if ((-iquantizershift-specExp) < 0)
210        accu <<= -(-iquantizershift-specExp);
211      else
212        accu >>= -iquantizershift-specExp;
213
214      mdctSpectrum[line] = -accu;
215    }
216    else if (quantSpectrum[line] > 0) {
217      FIXP_DBL accu;
218      INT ex,specExp,tabIndex;
219      FIXP_DBL s,t;
220
221      accu = (FIXP_DBL)(INT)quantSpectrum[line];
222
223      ex = CountLeadingBits(accu);
224      accu <<= ex;
225      specExp = (DFRACT_BITS-1) - ex;
226
227      FDK_ASSERT(specExp < 14);       /* this fails if abs(value) > 8191 */
228
229      tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE);
230
231      /* calculate "mantissa" ^4/3 */
232      s = FDKaacEnc_mTab_4_3Elc[tabIndex];
233
234      /* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */
235      t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp];
236
237      /* multiply "mantissa" ^4/3 with exponent multiplier */
238      accu = fMult(s,t);
239
240      /* get approperiate exponent shifter */
241      specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp]-1; /* -1 to avoid overflows in accu */
242
243      if (( -iquantizershift-specExp) < 0)
244        accu <<= -(-iquantizershift-specExp);
245      else
246        accu >>= -iquantizershift-specExp;
247
248      mdctSpectrum[line] = accu;
249    }
250    else {
251      mdctSpectrum[line] = FL2FXCONST_DBL(0.0f);
252    }
253  }
254}
255
256/*****************************************************************************
257
258    functionname: FDKaacEnc_QuantizeSpectrum
259    description: quantizes the entire spectrum
260    returns:
261    input: number of scalefactor bands to be quantized, ...
262    output: quantized spectrum
263
264*****************************************************************************/
265void FDKaacEnc_QuantizeSpectrum(INT sfbCnt,
266                      INT maxSfbPerGroup,
267                      INT sfbPerGroup,
268                      INT *sfbOffset,
269                      FIXP_DBL *mdctSpectrum,
270                      INT globalGain,
271                      INT *scalefactors,
272                      SHORT *quantizedSpectrum,
273                      INT dZoneQuantEnable)
274{
275  INT sfbOffs,sfb;
276
277  /* in FDKaacEnc_quantizeLines quaSpectrum is calculated with:
278        spec^(3/4) * 2^(-3/16*QSS) * 2^(3/4*scale) + k
279     simplify scaling calculation and reduce QSS before:
280        spec^(3/4) * 2^(-3/16*(QSS - 4*scale)) */
281
282  for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup)
283  for (sfb = 0; sfb < maxSfbPerGroup; sfb++)
284  {
285    INT scalefactor = scalefactors[sfbOffs+sfb] ;
286
287    FDKaacEnc_quantizeLines(globalGain - scalefactor, /* QSS */
288                  sfbOffset[sfbOffs+sfb+1] - sfbOffset[sfbOffs+sfb],
289                  mdctSpectrum + sfbOffset[sfbOffs+sfb],
290                  quantizedSpectrum + sfbOffset[sfbOffs+sfb],
291                  dZoneQuantEnable);
292  }
293}
294
295/*****************************************************************************
296
297    functionname: FDKaacEnc_calcSfbDist
298    description: calculates distortion of quantized values
299    returns: distortion
300    input: gain, number of lines to process, spectral data
301    output:
302
303*****************************************************************************/
304FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum,
305                     SHORT *quantSpectrum,
306                     INT noOfLines,
307                     INT gain,
308                     INT dZoneQuantEnable
309                     )
310{
311  INT i,scale;
312  FIXP_DBL xfsf;
313  FIXP_DBL diff;
314  FIXP_DBL invQuantSpec;
315
316  xfsf = FL2FXCONST_DBL(0.0f);
317
318  for (i=0; i<noOfLines; i++) {
319    /* quantization */
320    FDKaacEnc_quantizeLines(gain,
321                  1,
322                 &mdctSpectrum[i],
323                 &quantSpectrum[i],
324                  dZoneQuantEnable);
325
326    if (fAbs(quantSpectrum[i])>MAX_QUANT) {
327      return FL2FXCONST_DBL(0.0f);
328    }
329    /* inverse quantization */
330    FDKaacEnc_invQuantizeLines(gain,1,&quantSpectrum[i],&invQuantSpec);
331
332    /* dist */
333    diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i]>>1));
334
335    scale = CountLeadingBits(diff);
336    diff = scaleValue(diff, scale);
337    diff = fPow2(diff);
338    scale = fixMin(2*(scale-1), DFRACT_BITS-1);
339
340    diff = scaleValue(diff, -scale);
341
342    xfsf = xfsf + diff;
343  }
344
345  xfsf = CalcLdData(xfsf);
346
347  return xfsf;
348}
349
350/*****************************************************************************
351
352    functionname: FDKaacEnc_calcSfbQuantEnergyAndDist
353    description: calculates energy and distortion of quantized values
354    returns:
355    input: gain, number of lines to process, quantized spectral data,
356           spectral data
357    output: energy, distortion
358
359*****************************************************************************/
360void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum,
361                               SHORT *quantSpectrum,
362                               INT noOfLines,
363                               INT gain,
364                               FIXP_DBL *en,
365                               FIXP_DBL *dist)
366{
367  INT i,scale;
368  FIXP_DBL invQuantSpec;
369  FIXP_DBL diff;
370
371  FIXP_DBL energy = FL2FXCONST_DBL(0.0f);
372  FIXP_DBL distortion = FL2FXCONST_DBL(0.0f);
373
374  for (i=0; i<noOfLines; i++) {
375
376    if (fAbs(quantSpectrum[i])>MAX_QUANT) {
377      *en   = FL2FXCONST_DBL(0.0f);
378      *dist = FL2FXCONST_DBL(0.0f);
379      return;
380    }
381
382    /* inverse quantization */
383    FDKaacEnc_invQuantizeLines(gain,1,&quantSpectrum[i],&invQuantSpec);
384
385    /* energy */
386    energy += fPow2(invQuantSpec);
387
388    /* dist */
389    diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i]>>1));
390
391    scale = CountLeadingBits(diff);
392    diff = scaleValue(diff, scale);
393    diff = fPow2(diff);
394
395    scale = fixMin(2*(scale-1), DFRACT_BITS-1);
396
397    diff = scaleValue(diff, -scale);
398
399    distortion += diff;
400  }
401
402  *en   = CalcLdData(energy)+FL2FXCONST_DBL(0.03125f);
403  *dist = CalcLdData(distortion);
404}
405
406