1/* ----------------------------------------------------------------------------- 2Software License for The Fraunhofer FDK AAC Codec Library for Android 3 4© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten 5Forschung e.V. All rights reserved. 6 7 1. INTRODUCTION 8The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software 9that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding 10scheme for digital audio. This FDK AAC Codec software is intended to be used on 11a wide variety of Android devices. 12 13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient 14general perceptual audio codecs. AAC-ELD is considered the best-performing 15full-bandwidth communications codec by independent studies and is widely 16deployed. AAC has been standardized by ISO and IEC as part of the MPEG 17specifications. 18 19Patent licenses for necessary patent claims for the FDK AAC Codec (including 20those of Fraunhofer) may be obtained through Via Licensing 21(www.vialicensing.com) or through the respective patent owners individually for 22the purpose of encoding or decoding bit streams in products that are compliant 23with the ISO/IEC MPEG audio standards. Please note that most manufacturers of 24Android devices already license these patent claims through Via Licensing or 25directly from the patent owners, and therefore FDK AAC Codec software may 26already be covered under those patent licenses when it is used for those 27licensed purposes only. 28 29Commercially-licensed AAC software libraries, including floating-point versions 30with enhanced sound quality, are also available from Fraunhofer. Users are 31encouraged to check the Fraunhofer website for additional applications 32information and documentation. 33 342. COPYRIGHT LICENSE 35 36Redistribution and use in source and binary forms, with or without modification, 37are permitted without payment of copyright license fees provided that you 38satisfy the following conditions: 39 40You must retain the complete text of this software license in redistributions of 41the FDK AAC Codec or your modifications thereto in source code form. 42 43You must retain the complete text of this software license in the documentation 44and/or other materials provided with redistributions of the FDK AAC Codec or 45your modifications thereto in binary form. You must make available free of 46charge copies of the complete source code of the FDK AAC Codec and your 47modifications thereto to recipients of copies in binary form. 48 49The name of Fraunhofer may not be used to endorse or promote products derived 50from this library without prior written permission. 51 52You may not charge copyright license fees for anyone to use, copy or distribute 53the FDK AAC Codec software or your modifications thereto. 54 55Your modified versions of the FDK AAC Codec must carry prominent notices stating 56that you changed the software and the date of any change. For modified versions 57of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" 58must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK 59AAC Codec Library for Android." 60 613. NO PATENT LICENSE 62 63NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without 64limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. 65Fraunhofer provides no warranty of patent non-infringement with respect to this 66software. 67 68You may use this FDK AAC Codec software or modifications thereto only for 69purposes that are authorized by appropriate patent licenses. 70 714. DISCLAIMER 72 73This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright 74holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, 75including but not limited to the implied warranties of merchantability and 76fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 77CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, 78or consequential damages, including but not limited to procurement of substitute 79goods or services; loss of use, data, or profits, or business interruption, 80however caused and on any theory of liability, whether in contract, strict 81liability, or tort (including negligence), arising in any way out of the use of 82this software, even if advised of the possibility of such damage. 83 845. CONTACT INFORMATION 85 86Fraunhofer Institute for Integrated Circuits IIS 87Attention: Audio and Multimedia Departments - FDK AAC LL 88Am Wolfsmantel 33 8991058 Erlangen, Germany 90 91www.iis.fraunhofer.de/amm 92amm-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*****************************************************************************/ 116static 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*****************************************************************************/ 180static 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*****************************************************************************/ 278void 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*****************************************************************************/ 312FIXP_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*****************************************************************************/ 361void 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