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