1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software 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
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17 
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24 
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28 
29 2.    COPYRIGHT LICENSE
30 
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33 
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36 
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41 
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44 
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47 
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and 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 
53 3.    NO PATENT LICENSE
54 
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58 
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61 
62 4.    DISCLAIMER
63 
64 This 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
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72 
73 5.    CONTACT INFORMATION
74 
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79 
80 www.iis.fraunhofer.de/amm
81 amm-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 *****************************************************************************/
FDKaacEnc_quantizeLines(INT gain,INT noOfLines,FIXP_DBL * mdctSpectrum,SHORT * quaSpectrum)104 static 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 *****************************************************************************/
FDKaacEnc_invQuantizeLines(INT gain,INT noOfLines,SHORT * quantSpectrum,FIXP_DBL * mdctSpectrum)161 static 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 *****************************************************************************/
FDKaacEnc_QuantizeSpectrum(INT sfbCnt,INT maxSfbPerGroup,INT sfbPerGroup,INT * sfbOffset,FIXP_DBL * mdctSpectrum,INT globalGain,INT * scalefactors,SHORT * quantizedSpectrum)259 void 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 *****************************************************************************/
FDKaacEnc_calcSfbDist(FIXP_DBL * mdctSpectrum,SHORT * quantSpectrum,INT noOfLines,INT gain)296 FIXP_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 *****************************************************************************/
FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL * mdctSpectrum,SHORT * quantSpectrum,INT noOfLines,INT gain,FIXP_DBL * en,FIXP_DBL * dist)350 void 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