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