diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2012-07-11 10:15:24 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2012-07-11 10:15:24 -0700 |
commit | 2228e360595641dd906bf1773307f43d304f5b2e (patch) | |
tree | 57f3d390ebb0782cc0de0fb984c8ea7e45b4f386 /libAACenc/src/quantize.cpp | |
download | ODR-AudioEnc-2228e360595641dd906bf1773307f43d304f5b2e.tar.gz ODR-AudioEnc-2228e360595641dd906bf1773307f43d304f5b2e.tar.bz2 ODR-AudioEnc-2228e360595641dd906bf1773307f43d304f5b2e.zip |
Snapshot 2bda038c163298531d47394bc2c09e1409c5d0db
Change-Id: If584e579464f28b97d50e51fc76ba654a5536c54
Diffstat (limited to 'libAACenc/src/quantize.cpp')
-rw-r--r-- | libAACenc/src/quantize.cpp | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/libAACenc/src/quantize.cpp b/libAACenc/src/quantize.cpp new file mode 100644 index 0000000..9694901 --- /dev/null +++ b/libAACenc/src/quantize.cpp @@ -0,0 +1,385 @@ + +/* ----------------------------------------------------------------------------------------------------------- +Software License for The Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + All rights reserved. + + 1. INTRODUCTION +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements +the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. +This FDK AAC Codec software is intended to be used on a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual +audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by +independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part +of the MPEG specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) +may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners +individually for the purpose of encoding or decoding bit streams in products that are compliant with +the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license +these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec +software may already be covered under those patent licenses when it is used for those licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, +are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional +applications information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, are permitted without +payment of copyright license fees provided that you satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of the FDK AAC Codec or +your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation and/or other materials +provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. +You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived from this library without +prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec +software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software +and the date of any change. For modified versions of the FDK AAC Codec, the term +"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term +"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, +ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with +respect to this software. + +You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized +by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors +"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties +of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, +including but not limited to procurement of substitute goods or services; loss of use, data, or profits, +or business interruption, however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of this software, even if +advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------------------------------------- */ + +/******************************** MPEG Audio Encoder ************************** + + Initial author: M.Werner + contents/description: Quantization + +******************************************************************************/ + +#include "quantize.h" + +#include "aacEnc_rom.h" + +/***************************************************************************** + + functionname: FDKaacEnc_quantizeLines + description: quantizes spectrum lines + returns: + input: global gain, number of lines to process, spectral data + output: quantized spectrum + +*****************************************************************************/ +static void FDKaacEnc_quantizeLines(INT gain, + INT noOfLines, + FIXP_DBL *mdctSpectrum, + SHORT *quaSpectrum) +{ + int line; + FIXP_DBL k = FL2FXCONST_DBL(-0.0946f + 0.5f)>>16; + FIXP_QTD quantizer = FDKaacEnc_quantTableQ[(-gain)&3]; + INT quantizershift = ((-gain)>>2)+1; + + + for (line = 0; line < noOfLines; line++) + { + FIXP_DBL accu = fMultDiv2(mdctSpectrum[line],quantizer); + + if (accu < FL2FXCONST_DBL(0.0f)) + { + accu=-accu; + /* normalize */ + INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not necessary here since test value is always > 0 */ + accu <<= accuShift; + INT tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE); + INT totalShift = quantizershift-accuShift+1; + accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],FDKaacEnc_quantTableE[totalShift&3]); + totalShift = (16-4)-(3*(totalShift>>2)); + FDK_ASSERT(totalShift >=0); /* MAX_QUANT_VIOLATION */ + accu>>=totalShift; + quaSpectrum[line] = (SHORT)(-((LONG)(k + accu) >> (DFRACT_BITS-1-16))); + } + else if(accu > FL2FXCONST_DBL(0.0f)) + { + /* normalize */ + INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not necessary here since test value is always > 0 */ + accu <<= accuShift; + INT tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE); + INT totalShift = quantizershift-accuShift+1; + accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],FDKaacEnc_quantTableE[totalShift&3]); + totalShift = (16-4)-(3*(totalShift>>2)); + FDK_ASSERT(totalShift >=0); /* MAX_QUANT_VIOLATION */ + accu>>=totalShift; + quaSpectrum[line] = (SHORT)((LONG)(k + accu) >> (DFRACT_BITS-1-16)); + } + else + quaSpectrum[line]=0; + } +} + + +/***************************************************************************** + + functionname:iFDKaacEnc_quantizeLines + description: iquantizes spectrum lines + mdctSpectrum = iquaSpectrum^4/3 *2^(0.25*gain) + input: global gain, number of lines to process,quantized spectrum + output: spectral data + +*****************************************************************************/ +static void FDKaacEnc_invQuantizeLines(INT gain, + INT noOfLines, + SHORT *quantSpectrum, + FIXP_DBL *mdctSpectrum) + +{ + INT iquantizermod; + INT iquantizershift; + INT line; + + iquantizermod = gain&3; + iquantizershift = gain>>2; + + for (line = 0; line < noOfLines; line++) { + + if(quantSpectrum[line] < 0) { + FIXP_DBL accu; + INT ex,specExp,tabIndex; + FIXP_DBL s,t; + + accu = (FIXP_DBL) -quantSpectrum[line]; + + ex = CountLeadingBits(accu); + accu <<= ex; + specExp = (DFRACT_BITS-1) - ex; + + FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */ + + tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE); + + /* calculate "mantissa" ^4/3 */ + s = FDKaacEnc_mTab_4_3Elc[tabIndex]; + + /* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */ + t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp]; + + /* multiply "mantissa" ^4/3 with exponent multiplier */ + accu = fMult(s,t); + + /* get approperiate exponent shifter */ + specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp]-1; /* -1 to avoid overflows in accu */ + + if ((-iquantizershift-specExp) < 0) + accu <<= -(-iquantizershift-specExp); + else + accu >>= -iquantizershift-specExp; + + mdctSpectrum[line] = -accu; + } + else if (quantSpectrum[line] > 0) { + FIXP_DBL accu; + INT ex,specExp,tabIndex; + FIXP_DBL s,t; + + accu = (FIXP_DBL)(INT)quantSpectrum[line]; + + ex = CountLeadingBits(accu); + accu <<= ex; + specExp = (DFRACT_BITS-1) - ex; + + FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */ + + tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE); + + /* calculate "mantissa" ^4/3 */ + s = FDKaacEnc_mTab_4_3Elc[tabIndex]; + + /* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */ + t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp]; + + /* multiply "mantissa" ^4/3 with exponent multiplier */ + accu = fMult(s,t); + + /* get approperiate exponent shifter */ + specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp]-1; /* -1 to avoid overflows in accu */ + + if (( -iquantizershift-specExp) < 0) + accu <<= -(-iquantizershift-specExp); + else + accu >>= -iquantizershift-specExp; + + mdctSpectrum[line] = accu; + } + else { + mdctSpectrum[line] = FL2FXCONST_DBL(0.0f); + } + } +} + +/***************************************************************************** + + functionname: FDKaacEnc_QuantizeSpectrum + description: quantizes the entire spectrum + returns: + input: number of scalefactor bands to be quantized, ... + output: quantized spectrum + +*****************************************************************************/ +void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, + INT maxSfbPerGroup, + INT sfbPerGroup, + INT *sfbOffset, + FIXP_DBL *mdctSpectrum, + INT globalGain, + INT *scalefactors, + SHORT *quantizedSpectrum) +{ + INT sfbOffs,sfb; + + /* in FDKaacEnc_quantizeLines quaSpectrum is calculated with: + spec^(3/4) * 2^(-3/16*QSS) * 2^(3/4*scale) + k + simplify scaling calculation and reduce QSS before: + spec^(3/4) * 2^(-3/16*(QSS - 4*scale)) */ + + for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) + for (sfb = 0; sfb < maxSfbPerGroup; sfb++) + { + INT scalefactor = scalefactors[sfbOffs+sfb] ; + + FDKaacEnc_quantizeLines(globalGain - scalefactor, /* QSS */ + sfbOffset[sfbOffs+sfb+1] - sfbOffset[sfbOffs+sfb], + mdctSpectrum + sfbOffset[sfbOffs+sfb], + quantizedSpectrum + sfbOffset[sfbOffs+sfb]); + } +} + +/***************************************************************************** + + functionname: FDKaacEnc_calcSfbDist + description: calculates distortion of quantized values + returns: distortion + input: gain, number of lines to process, spectral data + output: + +*****************************************************************************/ +FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum, + SHORT *quantSpectrum, + INT noOfLines, + INT gain + ) +{ + INT i,scale; + FIXP_DBL xfsf; + FIXP_DBL diff; + FIXP_DBL invQuantSpec; + + xfsf = FL2FXCONST_DBL(0.0f); + + for (i=0; i<noOfLines; i++) { + /* quantization */ + FDKaacEnc_quantizeLines(gain, + 1, + &mdctSpectrum[i], + &quantSpectrum[i]); + + /* inverse quantization */ + FDKaacEnc_invQuantizeLines(gain,1,&quantSpectrum[i],&invQuantSpec); + + /* dist */ + diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i]>>1)); + + scale = CountLeadingBits(diff); + diff = scaleValue(diff, scale); + diff = fPow2(diff); + scale = fixMin(2*(scale-1), DFRACT_BITS-1); + + diff = scaleValue(diff, -scale); + + xfsf = xfsf + diff; + } + + xfsf = CalcLdData(xfsf); + + return xfsf; +} + +/***************************************************************************** + + functionname: FDKaacEnc_calcSfbQuantEnergyAndDist + description: calculates energy and distortion of quantized values + returns: + input: gain, number of lines to process, quantized spectral data, + spectral data + output: energy, distortion + +*****************************************************************************/ +void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum, + SHORT *quantSpectrum, + INT noOfLines, + INT gain, + FIXP_DBL *en, + FIXP_DBL *dist) +{ + INT i,scale; + FIXP_DBL invQuantSpec; + FIXP_DBL diff; + + *en = FL2FXCONST_DBL(0.0f); + *dist = FL2FXCONST_DBL(0.0f); + + for (i=0; i<noOfLines; i++) { + /* inverse quantization */ + FDKaacEnc_invQuantizeLines(gain,1,&quantSpectrum[i],&invQuantSpec); + + /* energy */ + *en += fPow2(invQuantSpec); + + /* dist */ + diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i]>>1)); + + scale = CountLeadingBits(diff); + diff = scaleValue(diff, scale); + diff = fPow2(diff); + + scale = fixMin(2*(scale-1), DFRACT_BITS-1); + + diff = scaleValue(diff, -scale); + + *dist += diff; + } + + *en = CalcLdData(*en)+FL2FXCONST_DBL(0.03125f); + *dist = CalcLdData(*dist); +} + |