12228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* ----------------------------------------------------------------------------------------------------------- 32228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectSoftware License for The Fraunhofer FDK AAC Codec Library for Android 42228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 54f0d97057c5c640b25518358886f8c47da9fc052Jean-Michel Trivi� Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V. 62228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project All rights reserved. 72228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 82228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1. INTRODUCTION 92228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThe Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements 102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthe MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. 112228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThis FDK AAC Codec software is intended to be used on a wide variety of Android devices. 122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 132228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual 142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectaudio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by 152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectindependent studies and is widely deployed. AAC has been standardized by ISO and IEC as part 162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectof the MPEG specifications. 172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 182228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectPatent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) 192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectmay be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners 202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectindividually for the purpose of encoding or decoding bit streams in products that are compliant with 212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthe ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license 222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthese patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec 232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectsoftware may already be covered under those patent licenses when it is used for those licensed purposes only. 242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 252228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectCommercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, 262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectare also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional 272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectapplications information and documentation. 282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project2. COPYRIGHT LICENSE 302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 312228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectRedistribution and use in source and binary forms, with or without modification, are permitted without 322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectpayment of copyright license fees provided that you satisfy the following conditions: 332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 342228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must retain the complete text of this software license in redistributions of the FDK AAC Codec or 352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectyour modifications thereto in source code form. 362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 372228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must retain the complete text of this software license in the documentation and/or other materials 382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectprovided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. 392228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must make available free of charge copies of the complete source code of the FDK AAC Codec and your 402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectmodifications thereto to recipients of copies in binary form. 412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 422228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThe name of Fraunhofer may not be used to endorse or promote products derived from this library without 432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectprior written permission. 442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 452228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec 462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectsoftware or your modifications thereto. 472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 482228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYour modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software 492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectand the date of any change. For modified versions of the FDK AAC Codec, the term 502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term 512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." 522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project3. NO PATENT LICENSE 542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 552228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectNO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, 562228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with 572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectrespect to this software. 582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 592228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized 602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectby appropriate patent licenses. 612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project4. DISCLAIMER 632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 642228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThis FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors 652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties 662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectof merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 672228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectCONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, 682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectincluding but not limited to procurement of substitute goods or services; loss of use, data, or profits, 692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projector business interruption, however caused and on any theory of liability, whether in contract, strict 702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectliability, or tort (including negligence), arising in any way out of the use of this software, even if 712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectadvised of the possibility of such damage. 722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project5. CONTACT INFORMATION 742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 752228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFraunhofer Institute for Integrated Circuits IIS 762228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAttention: Audio and Multimedia Departments - FDK AAC LL 772228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAm Wolfsmantel 33 782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project91058 Erlangen, Germany 792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectwww.iis.fraunhofer.de/amm 812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectamm-info@iis.fraunhofer.de 822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project----------------------------------------------------------------------------------------------------------- */ 832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \file 862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Envelope calculation 872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The envelope adjustor compares the energies present in the transposed 892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project highband to the reference energies conveyed with the bitstream. 902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The highband is amplified (sometimes) or attenuated (mostly) to the 912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project desired level. 922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The spectral shape of the reference energies can be changed several times per 942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project frame if necessary. Each set of energy values corresponding to a certain range 952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project in time will be called an <em>envelope</em> here. 962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The bitstream supports several frequency scales and two resolutions. Normally, 972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project one or more QMF-subbands are grouped to one SBR-band. An envelope contains 982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project reference energies for each SBR-band. 992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project In addition to the energy envelopes, noise envelopes are transmitted that 1002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project define the ratio of energy which is generated by adding noise instead of 1012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project transposing the lowband. The noise envelopes are given in a coarser time 1022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and frequency resolution. 1032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project If a signal contains strong tonal components, synthetic sines can be 1042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project generated in individual SBR bands. 1052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project An overlap buffer of 6 QMF-timeslots is used to allow a more 1072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project flexible alignment of the envelopes in time that is not restricted to the 1082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project core codec's frame borders. 1092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Therefore the envelope adjustor has access to the spectral data of the 1102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project current frame as well as the last 6 QMF-timeslots of the previous frame. 1112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project However, in average only the data of 1 frame is being processed as 1122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the adjustor is called once per frame. 1132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Depending on the frequency range set in the bitstream, only QMF-subbands between 1152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project <em>lowSubband</em> and <em>highSubband</em> are adjusted. 1162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Scaling of spectral data to maximize SNR (see #QMF_SCALE_FACTOR) as well as a special Mantissa-Exponent format 1182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ( see calculateSbrEnvelope() ) are being used. The main entry point for this modules is calculateSbrEnvelope(). 1192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \sa sbr_scale.h, #QMF_SCALE_FACTOR, calculateSbrEnvelope(), \ref documentationOverview 1212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 1222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "env_calc.h" 1252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "sbrdec_freq_sca.h" 1272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "env_extr.h" 1282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "transcendent.h" 1292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "sbr_ram.h" 1302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "sbr_rom.h" 1312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "genericStds.h" /* need FDKpow() for debug outputs */ 1332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#if defined(__arm__) 1352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "arm/env_calc_arm.cpp" 1362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 1372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projecttypedef struct 1392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 1402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL nrgRef[MAX_FREQ_COEFFS]; 1412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL nrgEst[MAX_FREQ_COEFFS]; 1422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL nrgGain[MAX_FREQ_COEFFS]; 1432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL noiseLevel[MAX_FREQ_COEFFS]; 1442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL nrgSine[MAX_FREQ_COEFFS]; 1452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgRef_e[MAX_FREQ_COEFFS]; 1472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgEst_e[MAX_FREQ_COEFFS]; 1482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgGain_e[MAX_FREQ_COEFFS]; 1492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR noiseLevel_e[MAX_FREQ_COEFFS]; 1502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgSine_e[MAX_FREQ_COEFFS]; 1512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 1522228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectENV_CALC_NRGS; 1532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, 1552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *filtBuffer_e, 1562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *NrgGain, 1572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *NrgGain_e, 1582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int subbands); 1592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal, 1612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL **analysBufferImag, 1622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, int highSubband, 1632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int start_pos, int next_pos, 1642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR frameExp, 1652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *nrgEst, 1662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *nrgEst_e ); 1672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal, 1692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL **analysBufferImag, 1702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int nSfb, 1712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *freqBandTable, 1722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int start_pos, int next_pos, 1732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR input_e, 1742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *nrg_est, 1752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *nrg_est_e ); 1762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c, 1782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmpNoise, SCHAR tmpNoise_e, 1792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR sinePresentFlag, 1802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR sineMapped, 1812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noNoiseFlag); 1822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs, 1842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, 1852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int highSubband, 1862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *sumRef_m, 1872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *sumRef_e, 1882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *ptrAvgGain_m, 1892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *ptrAvgGain_e); 1902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal, 1922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ENV_CALC_NRGS* nrgs, 1932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *ptrHarmIndex, 1942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubbands, 1952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noSubbands, 1962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int scale_change, 1972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noNoiseFlag, 1982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int *ptrPhaseIndex, 1992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int fCldfb); 2002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void adjustTimeSlotHQ(FIXP_DBL *ptrReal, 2012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *ptrImag, 2022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, 2032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ENV_CALC_NRGS* nrgs, 2042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubbands, 2052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noSubbands, 2062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int scale_change, 2072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL smooth_ratio, 2082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noNoiseFlag, 2092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int filtBufferNoiseShift); 2102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 2132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Map sine flags from bitstream to QMF bands 2142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The bitstream carries only 1 sine flag per band and frame. 2162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function maps every sine flag from the bitstream to a specific QMF subband 2172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and to a specific envelope where the sine shall start. 2182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The result is stored in the vector sineMapped which contains one entry per 2192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project QMF subband. The value of an entry specifies the envelope where a sine 2202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shall start. A value of #MAX_ENVELOPES indicates that no sine is present 2212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project in the subband. 2222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The missing harmonics flags from the previous frame (harmFlagsPrev) determine 2232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if a sine starts at the beginning of the frame or at the transient position. 2242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Additionally, the flags in harmFlagsPrev are being updated by this function 2252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for the next frame. 2262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 2272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */ 2282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int nSfb, /*!< Number of bands in the table */ 2292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *addHarmonics, /*!< vector with 1 flag per sfb */ 2302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int *harmFlagsPrev, /*!< Packed 'addHarmonics' */ 2312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int tranEnv, /*!< Transient position */ 2322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *sineMapped) /*!< Resulting vector of sine start positions for each QMF band */ 2332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 2352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int i; 2362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband2 = freqBandTable[0]<<1; 2372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int bitcount = 0; 2382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int oldflags = *harmFlagsPrev; 2392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int newflags = 0; 2402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 2422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Format of harmFlagsPrev: 2432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project first word = flags for highest 16 sfb bands in use 2452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project second word = flags for next lower 16 sfb bands (if present) 2462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project third word = flags for lowest 16 sfb bands (if present) 2472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Up to MAX_FREQ_COEFFS sfb bands can be flagged for a sign. 2492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The lowest bit of the first word corresponds to the _highest_ sfb band in use. 2502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This is ensures that each flag is mapped to the same QMF band even after a 2512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project change of the crossover-frequency. 2522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 2532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Reset the output vector first */ 2562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemset(sineMapped, MAX_ENVELOPES,MAX_FREQ_COEFFS); /* MAX_ENVELOPES means 'no sine' */ 2572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project freqBandTable += nSfb; 2592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project addHarmonics += nSfb-1; 2602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (i=nSfb; i!=0; i--) { 2622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int ui = *freqBandTable--; /* Upper limit of the current scale factor band. */ 2632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int li = *freqBandTable; /* Lower limit of the current scale factor band. */ 2642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( *addHarmonics-- ) { /* There is a sine in this band */ 2662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project unsigned int mask = 1 << bitcount; 2682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project newflags |= mask; /* Set flag */ 2692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 2712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project If there was a sine in the last frame, let it continue from the first envelope on 2722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else start at the transient position. 2732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 2742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineMapped[(ui+li-lowSubband2) >> 1] = ( oldflags & mask ) ? 0 : tranEnv; 2752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ((++bitcount == 16) || i==1) { 2782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bitcount = 0; 2792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *harmFlagsPrev++ = newflags; 2802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project oldflags = *harmFlagsPrev; /* Fetch 16 of the old flags */ 2812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project newflags = 0; 2822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 2852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 2882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Reduce gain-adjustment induced aliasing for real valued filterbank. 2892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 2902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void 2912228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectaliasingReduction(FIXP_DBL* degreeAlias, /*!< estimated aliasing for each QMF channel */ 2922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ENV_CALC_NRGS* nrgs, 2932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int* useAliasReduction, /*!< synthetic sine engergy for each subband, used as flag */ 2942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noSubbands) /*!< number of QMF channels to process */ 2952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 2962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL* nrgGain = nrgs->nrgGain; /*!< subband gains to be modified */ 2972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR* nrgGain_e = nrgs->nrgGain_e; /*!< subband gains to be modified (exponents) */ 2982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL* nrgEst = nrgs->nrgEst; /*!< subband energy before amplification */ 2992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR* nrgEst_e = nrgs->nrgEst_e; /*!< subband energy before amplification (exponents) */ 3002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int grouping = 0, index = 0, noGroups, k; 3012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int groupVector[MAX_FREQ_COEFFS]; 3022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Calculate grouping*/ 3042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = 0; k < noSubbands-1; k++ ){ 3052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( (degreeAlias[k + 1] != FL2FXCONST_DBL(0.0f)) && useAliasReduction[k] ) { 3062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(grouping==0){ 3072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project groupVector[index++] = k; 3082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project grouping = 1; 3092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else{ 3112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(groupVector[index-1] + 3 == k){ 3122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project groupVector[index++] = k + 1; 3132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project grouping = 0; 3142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else{ 3182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(grouping){ 3192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(useAliasReduction[k]) 3202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project groupVector[index++] = k + 1; 3212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 3222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project groupVector[index++] = k; 3232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project grouping = 0; 3242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(grouping){ 3292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project groupVector[index++] = noSubbands; 3302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noGroups = index >> 1; 3322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /*Calculate new gain*/ 3352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (int group = 0; group < noGroups; group ++) { 3362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL nrgOrig = FL2FXCONST_DBL(0.0f); /* Original signal energy in current group of bands */ 3372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgOrig_e = 0; 3382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL nrgAmp = FL2FXCONST_DBL(0.0f); /* Amplified signal energy in group (using current gains) */ 3392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgAmp_e = 0; 3402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL nrgMod = FL2FXCONST_DBL(0.0f); /* Signal energy in group when applying modified gains */ 3412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgMod_e = 0; 3422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL groupGain; /* Total energy gain in group */ 3432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR groupGain_e; 3442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL compensation; /* Compensation factor for the energy change when applying modified gains */ 3452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR compensation_e; 3462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int startGroup = groupVector[2*group]; 3482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int stopGroup = groupVector[2*group+1]; 3492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Calculate total energy in group before and after amplification with current gains: */ 3512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k = startGroup; k < stopGroup; k++){ 3522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Get original band energy */ 3532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp = nrgEst[k]; 3542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR tmp_e = nrgEst_e[k]; 3552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp(tmp, tmp_e, nrgOrig, nrgOrig_e, &nrgOrig, &nrgOrig_e); 3572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Multiply band energy with current gain */ 3592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmp = fMult(tmp,nrgGain[k]); 3602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmp_e = tmp_e + nrgGain_e[k]; 3612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp(tmp, tmp_e, nrgAmp, nrgAmp_e, &nrgAmp, &nrgAmp_e); 3632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Calculate total energy gain in group */ 3662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp(nrgAmp, nrgAmp_e, 3672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgOrig, nrgOrig_e, 3682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &groupGain, &groupGain_e); 3692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k = startGroup; k < stopGroup; k++){ 3712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp; 3722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR tmp_e; 3732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL alpha = degreeAlias[k]; 3752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (k < noSubbands - 1) { 3762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (degreeAlias[k + 1] > alpha) 3772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project alpha = degreeAlias[k + 1]; 3782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Modify gain depending on the degree of aliasing */ 3812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp( fMult(alpha,groupGain), groupGain_e, 3822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fMult(/*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - alpha,nrgGain[k]), nrgGain_e[k], 3832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &nrgGain[k], &nrgGain_e[k] ); 3842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Apply modified gain to original energy */ 3862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmp = fMult(nrgGain[k],nrgEst[k]); 3872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmp_e = nrgGain_e[k] + nrgEst_e[k]; 3882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Accumulate energy with modified gains applied */ 3902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp( tmp, tmp_e, 3912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgMod, nrgMod_e, 3922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &nrgMod, &nrgMod_e ); 3932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Calculate compensation factor to retain the energy of the amplified signal */ 3962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp(nrgAmp, nrgAmp_e, 3972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgMod, nrgMod_e, 3982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &compensation, &compensation_e); 3992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Apply compensation factor to all gains of the group */ 4012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k = startGroup; k < stopGroup; k++){ 4022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgGain[k] = fMult(nrgGain[k],compensation); 4032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgGain_e[k] = nrgGain_e[k] + compensation_e; 4042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 4052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 4062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 4072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Convert headroom bits to exponent */ 4102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define SCALE2EXP(s) (15-(s)) 4112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define EXP2SCALE(e) (15-(e)) 4122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 4142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Apply spectral envelope to subband samples 4152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function is called from sbr_dec.cpp in each frame. 4172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project To enhance accuracy and due to the usage of tables for squareroots and 4192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project inverse, some calculations are performed with the operands being split 4202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project into mantissa and exponent. The variable names in the source code carry 4212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the suffixes <em>_m</em> and <em>_e</em> respectively. The control data 4222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project in #hFrameData containts envelope data which is represented by this format but 4232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project stored in single words. (See requantizeEnvelopeData() for details). This data 4242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project is unpacked within calculateSbrEnvelope() to follow the described suffix convention. 4252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The actual value (comparable to the corresponding float-variable in the 4272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project research-implementation) of a mantissa/exponent-pair can be calculated as 4282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \f$ value = value\_m * 2^{value\_e} \f$ 4302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project All energies and noise levels decoded from the bitstream suit for an 4322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project original signal magnitude of \f$\pm 32768 \f$ rather than \f$ \pm 1\f$. Therefore, 4332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the scale factor <em>hb_scale</em> passed into this function will be converted 4342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project to an 'input exponent' (#input_e), which fits the internal representation. 4352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Before the actual processing, an exponent #adj_e for resulting adjusted 4372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project samples is derived from the maximum reference energy. 4382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Then, for each envelope, the following steps are performed: 4402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \li Calculate energy in the signal to be adjusted. Depending on the the value of 4422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project #interpolFreq (interpolation mode), this is either done seperately 4432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for each QMF-subband or for each SBR-band. 4442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The resulting energies are stored in #nrgEst_m[#MAX_FREQ_COEFFS] (mantissas) 4452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and #nrgEst_e[#MAX_FREQ_COEFFS] (exponents). 4462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \li Calculate gain and noise level for each subband:<br> 4472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \f$ gain = \sqrt{ \frac{nrgRef}{nrgEst} \cdot (1 - noiseRatio) } 4482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \hspace{2cm} 4492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noise = \sqrt{ nrgRef \cdot noiseRatio } 4502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \f$<br> 4512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project where <em>noiseRatio</em> and <em>nrgRef</em> are extracted from the 4522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bitstream and <em>nrgEst</em> is the subband energy before adjustment. 4532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The resulting gains are stored in #nrgGain_m[#MAX_FREQ_COEFFS] 4542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (mantissas) and #nrgGain_e[#MAX_FREQ_COEFFS] (exponents), the noise levels 4552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project are stored in #noiseLevel_m[#MAX_FREQ_COEFFS] and #noiseLevel_e[#MAX_FREQ_COEFFS] 4562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (exponents). 4572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The sine levels are stored in #nrgSine_m[#MAX_FREQ_COEFFS] 4582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and #nrgSine_e[#MAX_FREQ_COEFFS]. 4592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \li Noise limiting: The gain for each subband is limited both absolutely 4602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and relatively compared to the total gain over all subbands. 4612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \li Boost gain: Calculate and apply boost factor for each limiter band 4622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project in order to compensate for the energy loss imposed by the limiting. 4632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \li Apply gains and add noise: The gains and noise levels are applied 4642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project to all timeslots of the current envelope. A short FIR-filter (length 4 4652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project QMF-timeslots) can be used to smooth the sudden change at the envelope borders. 4662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Each complex subband sample of the current timeslot is multiplied by the 4672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smoothed gain, then random noise with the calculated level is added. 4682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \note 4702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project To reduce the stack size, some of the local arrays could be located within 4712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the time output buffer. Of the 512 samples temporarily available there, 4722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project about half the size is already used by #SBR_FRAME_DATA. A pointer to the 4732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project remaining free memory could be supplied by an additional argument to calculateSbrEnvelope() 4742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project in sbr_dec: 4752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \par 4772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \code 4782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project calculateSbrEnvelope (&hSbrDec->sbrScaleFactor, 4792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &hSbrDec->SbrCalculateEnvelope, 4802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hHeaderData, 4812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFrameData, 4822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project QmfBufferReal, 4832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project QmfBufferImag, 4842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project timeOutPtr + sizeof(SBR_FRAME_DATA)/sizeof(Float) + 1); 4852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \endcode 4862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \par 4882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Within calculateSbrEnvelope(), some pointers could be defined instead of the arrays 4892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project #nrgRef_m, #nrgRef_e, #nrgEst_m, #nrgEst_e, #noiseLevel_m: 4902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \par 4922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \code 4932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fract* nrgRef_m = timeOutPtr; 4942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR* nrgRef_e = nrgRef_m + MAX_FREQ_COEFFS; 4952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fract* nrgEst_m = nrgRef_e + MAX_FREQ_COEFFS; 4962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR* nrgEst_e = nrgEst_m + MAX_FREQ_COEFFS; 4972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fract* noiseLevel_m = nrgEst_e + MAX_FREQ_COEFFS; 4982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \endcode 4992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project <br> 5012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 5022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid 5032228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectcalculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */ 5042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, /*!< Handle to struct filled by the create-function */ 5052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ 5062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */ 5072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL **analysBufferReal, /*!< Real part of subband samples to be processed */ 5082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL **analysBufferImag, /*!< Imag part of subband samples to be processed */ 5092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const int useLP, 5102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *degreeAlias, /*!< Estimated aliasing for each QMF channel */ 5112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const UINT flags, 5122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const int frameErrorFlag 5132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 5142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 5152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int c, i, j, envNoise = 0; 5162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR* borders = hFrameData->frameInfo.borders; 5172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL *noiseLevels = hFrameData->sbrNoiseFloorLevel; 5192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData; 5202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband = hFreq->lowSubband; 5222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int highSubband = hFreq->highSubband; 5232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noSubbands = highSubband - lowSubband; 5242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noNoiseBands = hFreq->nNfb; 5262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int no_cols = hHeaderData->numberTimeSlots * hHeaderData->timeStep; 5272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR first_start = borders[0] * hHeaderData->timeStep; 5282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR sineMapped[MAX_FREQ_COEFFS]; 5302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR ov_adj_e = SCALE2EXP(sbrScaleFactor->ov_hb_scale); 5312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR adj_e = 0; 5322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR output_e; 5332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR final_e = 0; 5342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR maxGainLimit_e = (frameErrorFlag) ? MAX_GAIN_CONCEAL_EXP : MAX_GAIN_EXP; 5362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int useAliasReduction[64]; 5382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR smooth_length = 0; 5392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL * pIenv = hFrameData->iEnvelope; 5412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 5432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Extract sine flags for all QMF bands 5442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 5452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project mapSineFlags(hFreq->freqBandTable[1], 5462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFreq->nSfb[1], 5472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFrameData->addHarmonics, 5482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->harmFlagsPrev, 5492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFrameData->frameInfo.tranEnv, 5502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineMapped); 5512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 5542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Scan for maximum in bufferd noise levels. 5552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This is needed in case that we had strong noise in the previous frame 5562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project which is smoothed into the current frame. 5572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The resulting exponent is used as start value for the maximum search 5582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project in reference energies 5592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 5602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 5612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project adj_e = h_sbr_cal_env->filtBufferNoise_e - getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands); 5622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 5642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Scan for maximum reference energy to be able 5652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project to select appropriate values for adj_e and final_e. 5662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 5672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) { 5692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project INT maxSfbNrg_e = -FRACT_BITS+NRG_EXP_OFFSET; /* start value for maximum search */ 5702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Fetch frequency resolution for current envelope: */ 5722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (j=hFreq->nSfb[hFrameData->frameInfo.freqRes[i]]; j!=0; j--) { 5732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxSfbNrg_e = fixMax(maxSfbNrg_e,(INT)((LONG)(*pIenv++) & MASK_E)); 5742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxSfbNrg_e -= NRG_EXP_OFFSET; 5762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Energy -> magnitude (sqrt halfens exponent) */ 5782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxSfbNrg_e = (maxSfbNrg_e+1) >> 1; /* +1 to go safe (round to next higher int) */ 5792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Some safety margin is needed for 2 reasons: 5812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project - The signal energy is not equally spread over all subband samples in 5822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project a specific sfb of an envelope (Nrg could be too high by a factor of 5832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project envWidth * sfbWidth) 5842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project - Smoothing can smear high gains of the previous envelope into the current 5852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 5862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxSfbNrg_e += 6; 5872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (borders[i] < hHeaderData->numberTimeSlots) 5892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* This envelope affects timeslots that belong to the output frame */ 5902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project adj_e = (maxSfbNrg_e > adj_e) ? maxSfbNrg_e : adj_e; 5912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (borders[i+1] > hHeaderData->numberTimeSlots) 5932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* This envelope affects timeslots after the output frame */ 5942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project final_e = (maxSfbNrg_e > final_e) ? maxSfbNrg_e : final_e; 5952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 5992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Calculate adjustment factors and apply them for every envelope. 6002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 6012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pIenv = hFrameData->iEnvelope; 6022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) { 6042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k, noNoiseFlag; 6062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR noise_e, input_e = SCALE2EXP(sbrScaleFactor->hb_scale); 6072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project C_ALLOC_SCRATCH_START(pNrgs, ENV_CALC_NRGS, 1); 6082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 6102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Helper variables. 6112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 6122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR start_pos = hHeaderData->timeStep * borders[i]; /* Start-position in time (subband sample) for current envelope. */ 6132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR stop_pos = hHeaderData->timeStep * borders[i+1]; /* Stop-position in time (subband sample) for current envelope. */ 6142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR freq_res = hFrameData->frameInfo.freqRes[i]; /* Frequency resolution for current envelope. */ 6152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Always do fully initialize the temporary energy table. This prevents negative energies and extreme gain factors in 6182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project cases where the number of limiter bands exceeds the number of subbands. The latter can be caused by undetected bit 6192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project errors and is tested by some streams from the certification set. */ 6202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemclear(pNrgs, sizeof(ENV_CALC_NRGS)); 6212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* If the start-pos of the current envelope equals the stop pos of the current 6232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noise envelope, increase the pointer (i.e. choose the next noise-floor).*/ 6242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (borders[i] == hFrameData->frameInfo.bordersNoise[envNoise+1]){ 6252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noiseLevels += noNoiseBands; /* The noise floor data is stored in a row [noiseFloor1 noiseFloor2...].*/ 6262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project envNoise++; 6272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(i==hFrameData->frameInfo.tranEnv || i==h_sbr_cal_env->prevTranEnv) /* attack */ 6302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 6312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noNoiseFlag = 1; 6322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 6332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smooth_length = 0; /* No smoothing on attacks! */ 6342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 6362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noNoiseFlag = 0; 6372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 6382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smooth_length = (1 - hHeaderData->bs_data.smoothingLength) << 2; /* can become either 0 or 4 */ 6392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 6432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Energy estimation in transposed highband. 6442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 6452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (hHeaderData->bs_data.interpolFreq) 6462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project calcNrgPerSubband(analysBufferReal, 6472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (useLP) ? NULL : analysBufferImag, 6482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, highSubband, 6492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project start_pos, stop_pos, 6502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project input_e, 6512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgEst, 6522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgEst_e); 6532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 6542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project calcNrgPerSfb(analysBufferReal, 6552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (useLP) ? NULL : analysBufferImag, 6562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFreq->nSfb[freq_res], 6572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFreq->freqBandTable[freq_res], 6582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project start_pos, stop_pos, 6592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project input_e, 6602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgEst, 6612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgEst_e); 6622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 6642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Calculate subband gains 6652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 6662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 6672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR * table = hFreq->freqBandTable[freq_res]; 6682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR * pUiNoise = &hFreq->freqBandTableNoise[1]; /*! Upper limit of the current noise floor band. */ 6692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL * pNoiseLevels = noiseLevels; 6712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmpNoise = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M)); 6732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR tmpNoise_e = (UCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET; 6742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int cc = 0; 6762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project c = 0; 6772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (j = 0; j < hFreq->nSfb[freq_res]; j++) { 6782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL refNrg = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pIenv) & MASK_M)); 6802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR refNrg_e = (SCHAR)((LONG)(*pIenv) & MASK_E) - NRG_EXP_OFFSET; 6812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR sinePresentFlag = 0; 6832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int li = table[j]; 6842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int ui = table[j+1]; 6852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=li; k<ui; k++) { 6872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sinePresentFlag |= (i >= sineMapped[cc]); 6882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project cc++; 6892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=li; k<ui; k++) { 6922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (k >= *pUiNoise) { 6932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmpNoise = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M)); 6942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmpNoise_e = (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET; 6952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pUiNoise++; 6972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_ASSERT(k >= lowSubband); 7002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (useLP) 7022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project useAliasReduction[k-lowSubband] = !sinePresentFlag; 7032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f); 7052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgSine_e[c] = 0; 7062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project calcSubbandGain(refNrg, refNrg_e, pNrgs, c, 7082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmpNoise, tmpNoise_e, 7092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sinePresentFlag, i >= sineMapped[c], 7102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noNoiseFlag); 7112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgRef[c] = refNrg; 7132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgRef_e[c] = refNrg_e; 7142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project c++; 7162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pIenv++; 7182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 7222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Noise limiting 7232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 7242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (c = 0; c < hFreq->noLimiterBands; c++) { 7262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sumRef, boostGain, maxGain; 7282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL accu = FL2FXCONST_DBL(0.0f); 7292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR sumRef_e, boostGain_e, maxGain_e, accu_e = 0; 7302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project calcAvgGain(pNrgs, 7322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFreq->limiterBandTable[c], hFreq->limiterBandTable[c+1], 7332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &sumRef, &sumRef_e, 7342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &maxGain, &maxGain_e); 7352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Multiply maxGain with limiterGain: */ 7372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain = fMult(maxGain, FDK_sbrDecoder_sbr_limGains_m[hHeaderData->bs_data.limiterGains]); 7382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain_e += FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains]; 7392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Scale mantissa of MaxGain into range between 0.5 and 1: */ 7412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (maxGain == FL2FXCONST_DBL(0.0f)) 7422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain_e = -FRACT_BITS; 7432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 7442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR charTemp = CountLeadingBits(maxGain); 7452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain_e -= charTemp; 7462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain <<= (int)charTemp; 7472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (maxGain_e >= maxGainLimit_e) { /* upper limit (e.g. 96 dB) */ 7502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain = FL2FXCONST_DBL(0.5f); 7512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain_e = maxGainLimit_e; 7522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Every subband gain is compared to the scaled "average gain" 7562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and limited if necessary: */ 7572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c+1]; k++) { 7582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( (pNrgs->nrgGain_e[k] > maxGain_e) || (pNrgs->nrgGain_e[k] == maxGain_e && pNrgs->nrgGain[k]>maxGain) ) { 7592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL noiseAmp; 7612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR noiseAmp_e; 7622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp(maxGain, maxGain_e, pNrgs->nrgGain[k], pNrgs->nrgGain_e[k], &noiseAmp, &noiseAmp_e); 7642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->noiseLevel[k] = fMult(pNrgs->noiseLevel[k],noiseAmp); 7652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->noiseLevel_e[k] += noiseAmp_e; 7662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain[k] = maxGain; 7672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain_e[k] = maxGain_e; 7682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* -- Boost gain 7722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Calculate and apply boost factor for each limiter band: 7732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1. Check how much energy would be present when using the limited gain 7742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2. Calculate boost factor by comparison with reference energy 7752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3. Apply boost factor to compensate for the energy loss due to limiting 7762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 7772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; k++) { 7782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 1.a Add energy of adjusted signal (using preliminary gain) */ 7802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp = fMult(pNrgs->nrgGain[k],pNrgs->nrgEst[k]); 7812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR tmp_e = pNrgs->nrgGain_e[k] + pNrgs->nrgEst_e[k]; 7822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp(tmp, tmp_e, accu, accu_e, &accu, &accu_e); 7832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 1.b Add sine energy (if present) */ 7852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(pNrgs->nrgSine[k] != FL2FXCONST_DBL(0.0f)) { 7862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp(pNrgs->nrgSine[k], pNrgs->nrgSine_e[k], accu, accu_e, &accu, &accu_e); 7872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 7892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 1.c Add noise energy (if present) */ 7902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(noNoiseFlag == 0) { 7912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp(pNrgs->noiseLevel[k], pNrgs->noiseLevel_e[k], accu, accu_e, &accu, &accu_e); 7922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 2.a Calculate ratio of wanted energy and accumulated energy */ 7972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (accu == (FIXP_DBL)0) { /* If divisor is 0, limit quotient to +4 dB */ 7982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project boostGain = FL2FXCONST_DBL(0.6279716f); 7992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project boostGain_e = 2; 8002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 8012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project INT div_e; 8022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project boostGain = fDivNorm(sumRef, accu, &div_e); 8032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project boostGain_e = sumRef_e - accu_e + div_e; 8042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 2.b Result too high? --> Limit the boost factor to +4 dB */ 8082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if((boostGain_e > 3) || 8092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (boostGain_e == 2 && boostGain > FL2FXCONST_DBL(0.6279716f)) || 8102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (boostGain_e == 3 && boostGain > FL2FXCONST_DBL(0.3139858f)) ) 8112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 8122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project boostGain = FL2FXCONST_DBL(0.6279716f); 8132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project boostGain_e = 2; 8142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 3. Multiply all signal components with the boost factor */ 8162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; k++) { 8172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain[k] = fMultDiv2(pNrgs->nrgGain[k],boostGain); 8182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain_e[k] = pNrgs->nrgGain_e[k] + boostGain_e + 1; 8192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgSine[k] = fMultDiv2(pNrgs->nrgSine[k],boostGain); 8212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgSine_e[k] = pNrgs->nrgSine_e[k] + boostGain_e + 1; 8222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->noiseLevel[k] = fMultDiv2(pNrgs->noiseLevel[k],boostGain); 8242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->noiseLevel_e[k] = pNrgs->noiseLevel_e[k] + boostGain_e + 1; 8252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* End of noise limiting */ 8282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (useLP) 8302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project aliasingReduction(degreeAlias+lowSubband, 8312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs, 8322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project useAliasReduction, 8332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noSubbands); 8342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* For the timeslots within the range for the output frame, 8362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project use the same scale for the noise levels. 8372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Drawback: If the envelope exceeds the frame border, the noise levels 8382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project will have to be rescaled later to fit final_e of 8392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the gain-values. 8402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 8412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noise_e = (start_pos < no_cols) ? adj_e : final_e; 8422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 8442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Convert energies to amplitude levels 8452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 8462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) { 8472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_sqrt_MantExp(&pNrgs->nrgSine[k], &pNrgs->nrgSine_e[k], &noise_e); 8482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_sqrt_MantExp(&pNrgs->nrgGain[k], &pNrgs->nrgGain_e[k], &pNrgs->nrgGain_e[k]); 8492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_sqrt_MantExp(&pNrgs->noiseLevel[k], &pNrgs->noiseLevel_e[k], &noise_e); 8502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 8552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Apply calculated gains and adaptive noise 8562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 8572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* assembleHfSignals() */ 8592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 8602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int scale_change, sc_change; 8612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL smooth_ratio; 8622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int filtBufferNoiseShift=0; 8632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Initialize smoothing buffers with the first valid values */ 8652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (h_sbr_cal_env->startUp) 8662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 8672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) { 8682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise_e = noise_e; 8692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e, noSubbands*sizeof(SCHAR)); 8712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, noSubbands*sizeof(FIXP_DBL)); 8722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain, noSubbands*sizeof(FIXP_DBL)); 8732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->startUp = 0; 8762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) { 8792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project equalizeFiltBufferExp(h_sbr_cal_env->filtBuffer, /* buffered */ 8812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBuffer_e, /* buffered */ 8822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain, /* current */ 8832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain_e, /* current */ 8842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noSubbands); 8852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Adapt exponent of buffered noise levels to the current exponent 8872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project so they can easily be smoothed */ 8882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if((h_sbr_cal_env->filtBufferNoise_e - noise_e)>=0) { 8892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int shift = fixMin(DFRACT_BITS-1,(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e)); 8902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) 8912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise[k] <<= shift; 8922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 8942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int shift = fixMin(DFRACT_BITS-1,-(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e)); 8952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) 8962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise[k] >>= shift; 8972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise_e = noise_e; 9002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* find best scaling! */ 9032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change = -(DFRACT_BITS-1); 9042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k=0;k<noSubbands;k++) { 9052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change = fixMax(scale_change,(int)pNrgs->nrgGain_e[k]); 9062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sc_change = (start_pos<no_cols)? adj_e - input_e : final_e - input_e; 9082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ((scale_change-sc_change+1)<0) 9102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change-=(scale_change-sc_change+1); 9112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change = (scale_change-sc_change)+1; 9132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k=0;k<noSubbands;k++) { 9152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int sc = scale_change-pNrgs->nrgGain_e[k] + (sc_change-1); 9162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain[k] >>= sc; 9172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain_e[k] += sc; 9182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) { 9212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k=0;k<noSubbands;k++) { 9222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int sc = scale_change-h_sbr_cal_env->filtBuffer_e[k] + (sc_change-1); 9232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBuffer[k] >>= sc; 9242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (j = start_pos; j < stop_pos; j++) 9282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 9292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* This timeslot is located within the first part of the processing buffer 9302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and will be fed into the QMF-synthesis for the current frame. 9312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project adj_e - input_e 9322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This timeslot will not yet be fed into the QMF so we do not care 9332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project about the adj_e. 9342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sc_change = final_e - input_e 9352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 9362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( (j==no_cols) && (start_pos<no_cols) ) 9372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 9382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int shift = (int) (noise_e - final_e); 9392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 9402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBufferNoiseShift = shift; /* shifting of h_sbr_cal_env->filtBufferNoise[k] will be applied in function adjustTimeSlotHQ() */ 9412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (shift>=0) { 9422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = fixMin(DFRACT_BITS-1,shift); 9432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) { 9442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgSine[k] <<= shift; 9452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->noiseLevel[k] <<= shift; 9462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 9472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 9482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise[k] <<= shift; 9492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 9502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 9532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = fixMin(DFRACT_BITS-1,-shift); 9542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) { 9552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgSine[k] >>= shift; 9562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->noiseLevel[k] >>= shift; 9572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 9582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 9592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise[k] >>= shift; 9602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 9612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* update noise scaling */ 9652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noise_e = final_e; 9662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 9672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise_e = noise_e; /* scaling value unused! */ 9682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* update gain buffer*/ 9702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sc_change -= (final_e - input_e); 9712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (sc_change<0) { 9732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k=0;k<noSubbands;k++) { 9742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain[k] >>= -sc_change; 9752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain_e[k] += -sc_change; 9762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) { 9782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k=0;k<noSubbands;k++) { 9792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBuffer[k] >>= -sc_change; 9802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 9832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change+=sc_change; 9842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } // if 9872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) { 9892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Prevent the smoothing filter from running on constant levels */ 9912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (j-start_pos < smooth_length) 9922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j-start_pos]; 9932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 9952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smooth_ratio = FL2FXCONST_SGL(0.0f); 9962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project adjustTimeSlotHQ(&analysBufferReal[j][lowSubband], 9982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &analysBufferImag[j][lowSubband], 9992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env, 10002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs, 10012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, 10022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noSubbands, 10032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change, 10042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smooth_ratio, 10052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noNoiseFlag, 10062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBufferNoiseShift); 10072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 10092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 10102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project adjustTimeSlotLC(&analysBufferReal[j][lowSubband], 10112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs, 10122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &h_sbr_cal_env->harmIndex, 10132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, 10142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noSubbands, 10152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change, 10162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noNoiseFlag, 10172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &h_sbr_cal_env->phaseIndex, 10182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (flags & SBRDEC_ELD_GRID)); 10192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } // for 10212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) { 10232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Update time-smoothing-buffers for gains and noise levels 10242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The gains and the noise values of the current envelope are copied into the buffer. 10252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This has to be done at the end of each envelope as the values are required for 10262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project a smooth transition to the next envelope. */ 10272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain, noSubbands*sizeof(FIXP_DBL)); 10282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e, noSubbands*sizeof(SCHAR)); 10292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, noSubbands*sizeof(FIXP_DBL)); 10302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project C_ALLOC_SCRATCH_END(pNrgs, ENV_CALC_NRGS, 1); 10342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Rescale output samples */ 10372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 10382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL maxVal; 10392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int ov_reserve, reserve; 10402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Determine headroom in old adjusted samples */ 10422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal = maxSubbandSample( analysBufferReal, 10432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (useLP) ? NULL : analysBufferImag, 10442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, 10452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project highSubband, 10462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 0, 10472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project first_start); 10482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ov_reserve = fNorm(maxVal); 10502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Determine headroom in new adjusted samples */ 10522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal = maxSubbandSample( analysBufferReal, 10532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (useLP) ? NULL : analysBufferImag, 10542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, 10552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project highSubband, 10562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project first_start, 10572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project no_cols); 10582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project reserve = fNorm(maxVal); 10602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Determine common output exponent */ 10622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (ov_adj_e - ov_reserve > adj_e - reserve ) /* set output_e to the maximum */ 10632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project output_e = ov_adj_e - ov_reserve; 10642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 10652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project output_e = adj_e - reserve; 10662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Rescale old samples */ 10682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project rescaleSubbandSamples( analysBufferReal, 10692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (useLP) ? NULL : analysBufferImag, 10702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, highSubband, 10712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 0, first_start, 10722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ov_adj_e - output_e); 10732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Rescale new samples */ 10752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project rescaleSubbandSamples( analysBufferReal, 10762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (useLP) ? NULL : analysBufferImag, 10772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, highSubband, 10782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project first_start, no_cols, 10792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project adj_e - output_e); 10802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Update hb_scale */ 10832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sbrScaleFactor->hb_scale = EXP2SCALE(output_e); 10842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Save the current final exponent for the next frame: */ 10862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sbrScaleFactor->ov_hb_scale = EXP2SCALE(final_e); 10872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* We need to remeber to the next frame that the transient 10902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project will occur in the first envelope (if tranEnv == nEnvelopes). */ 10912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(hFrameData->frameInfo.tranEnv == hFrameData->frameInfo.nEnvelopes) 10922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->prevTranEnv = 0; 10932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 10942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->prevTranEnv = -1; 10952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 10972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 11002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Create envelope instance 11012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Must be called once for each channel before calculateSbrEnvelope() can be used. 11032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \return errorCode, 0 if successful 11052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 11062228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectSBR_ERROR 11072228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectcreateSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hs, /*!< pointer to envelope instance */ 11082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_SBR_HEADER_DATA hHeaderData, /*!< static SBR control data, initialized with defaults */ 11092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const int chan, /*!< Channel for which to assign buffers */ 11102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const UINT flags) 11112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 11122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SBR_ERROR err = SBRDEC_OK; 11132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int i; 11142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Clear previous missing harmonics flags */ 11162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (i=0; i<(MAX_FREQ_COEFFS+15)>>4; i++) { 11172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hs->harmFlagsPrev[i] = 0; 11182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hs->harmIndex = 0; 11202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 11222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Setup pointers for time smoothing. 11232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The buffer itself will be initialized later triggered by the startUp-flag. 11242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 11252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hs->prevTranEnv = -1; 11262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* initialization */ 11292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project resetSbrEnvelopeCalc(hs); 11302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (chan==0) { /* do this only once */ 11322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project err = resetFreqBandTables(hHeaderData, flags); 11332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return err; 11362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 11372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 11392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Create envelope instance 11402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Must be called once for each channel before calculateSbrEnvelope() can be used. 11422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \return errorCode, 0 if successful 11442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 11452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint 11462228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectdeleteSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hs) 11472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 11482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return 0; 11492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 11502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 11532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Reset envelope instance 11542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function must be called for each channel on a change of configuration. 11562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Note that resetFreqBandTables should also be called in this case. 11572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \return errorCode, 0 if successful 11592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 11602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid 11612228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectresetSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to envelope instance */ 11622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 11632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hCalEnv->phaseIndex = 0; 11642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Noise exponent needs to be reset because the output exponent for the next frame depends on it */ 11662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hCalEnv->filtBufferNoise_e = 0; 11672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hCalEnv->startUp = 1; 11692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 11702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 11732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Equalize exponents of the buffered gain values and the new ones 11742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project After equalization of exponents, the FIR-filter addition for smoothing 11762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project can be performed. 11772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function is called once for each envelope before adjusting. 11782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 11792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */ 11802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *filtBuffer_e, /*!< exponents of bufferd gains */ 11812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *nrgGain, /*!< gains for current envelope */ 11822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *nrgGain_e, /*!< exponents of gains for current envelope */ 11832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int subbands) /*!< Number of QMF subbands */ 11842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 11852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int band; 11862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int diff; 11872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (band=0; band<subbands; band++){ 11892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project diff = (int) (nrgGain_e[band] - filtBuffer_e[band]); 11902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (diff>0) { 11912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBuffer[band] >>= diff; /* Compensate for the scale change by shifting the mantissa. */ 11922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */ 11932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else if (diff<0) { 11952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The buffered gains seem to be larger, but maybe there 11962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project are some unused bits left in the mantissa */ 11972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int reserve = CntLeadingZeros(fixp_abs(filtBuffer[band]))-1; 11992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ((-diff) <= reserve) { 12012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* There is enough space in the buffered mantissa so 12022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project that we can take the new exponent as common. 12032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 12042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBuffer[band] <<= (-diff); 12052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBuffer_e[band] += diff; /* becomes equal to *ptrNewExp */ 12062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 12082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBuffer[band] <<= reserve; /* Shift the mantissa as far as possible: */ 12092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */ 12102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* For the remaining difference, change the new gain value */ 12122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project diff = fixMin(-(reserve + diff),DFRACT_BITS-1); 12132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgGain[band] >>= diff; 12142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgGain_e[band] += diff; 12152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 12192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 12212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Shift left the mantissas of all subband samples 12222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project in the giventime and frequency range by the specified number of bits. 12232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function is used to rescale the audio data in the overlap buffer 12252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project which has already been envelope adjusted with the last frame. 12262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 12272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid rescaleSubbandSamples(FIXP_DBL ** re, /*!< Real part of input and output subband samples */ 12282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL ** im, /*!< Imaginary part of input and output subband samples */ 12292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, /*!< Begin of frequency range to process */ 12302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int highSubband, /*!< End of frequency range to process */ 12312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int start_pos, /*!< Begin of time rage (QMF-timeslot) */ 12322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int next_pos, /*!< End of time rage (QMF-timeslot) */ 12332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int shift) /*!< number of bits to shift */ 12342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 12352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int width = highSubband-lowSubband; 12362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( (width > 0) && (shift!=0) ) { 12382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (im!=NULL) { 12392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (int l=start_pos; l<next_pos; l++) { 12402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scaleValues(&re[l][lowSubband], width, shift); 12412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scaleValues(&im[l][lowSubband], width, shift); 12422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else 12442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 12452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (int l=start_pos; l<next_pos; l++) { 12462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scaleValues(&re[l][lowSubband], width, shift); 12472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 12512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 12542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Determine headroom for shifting 12552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Determine by how much the spectrum can be shifted left 12572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for better accuracy in later processing. 12582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \return Number of free bits in the biggest spectral value 12602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 12612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12622228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output subband samples */ 12632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL ** im, /*!< Real part of input and output subband samples */ 12642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, /*!< Begin of frequency range to process */ 12652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int highSubband, /*!< Number of QMF bands to process */ 12662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int start_pos, /*!< Begin of time rage (QMF-timeslot) */ 12672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int next_pos /*!< End of time rage (QMF-timeslot) */ 12682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 12692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 12702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL maxVal = FL2FX_DBL(0.0f); 12712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project unsigned int width = highSubband - lowSubband; 12722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_ASSERT(width <= (64)); 12742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( width > 0 ) { 12762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (im!=NULL) 12772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 12782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (int l=start_pos; l<next_pos; l++) 12792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 12802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef FUNCTION_FDK_get_maxval 12812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal = FDK_get_maxval(maxVal, &re[l][lowSubband], &im[l][lowSubband], width); 12822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#else 12832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k=width; 12842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *reTmp = &re[l][lowSubband]; 12852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *imTmp = &im[l][lowSubband]; 12862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project do{ 12872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp1 = *(reTmp++); 12882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp2 = *(imTmp++); 12892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal |= (FIXP_DBL)((LONG)(tmp1)^((LONG)tmp1>>(DFRACT_BITS-1))); 12902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal |= (FIXP_DBL)((LONG)(tmp2)^((LONG)tmp2>>(DFRACT_BITS-1))); 12912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } while(--k!=0); 12922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 12932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else 12952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 12962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (int l=start_pos; l<next_pos; l++) { 12972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k=width; 12982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *reTmp = &re[l][lowSubband]; 12992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project do{ 13002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp = *(reTmp++); 13012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal |= (FIXP_DBL)((LONG)(tmp)^((LONG)tmp>>(DFRACT_BITS-1))); 13022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project }while(--k!=0); 13032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return(maxVal); 13082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 13092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define SHIFT_BEFORE_SQUARE (3) /* (7/2) */ 13112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!< 13122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project If the accumulator does not provide enough overflow bits or 13132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project does not provide a high dynamic range, the below energy calculation 13142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project requires an additional shift operation for each sample. 13152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project On the other hand, doing the shift allows using a single-precision 13162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project multiplication for the square (at least 16bit x 16bit). 13172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project For even values of OVRFLW_BITS (0, 2, 4, 6), saturated arithmetic 13182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project is required for the energy accumulation. 13192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Theoretically, the sample-squares can sum up to a value of 76, 13202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project requiring 7 overflow bits. However since such situations are *very* 13212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project rare, accu can be limited to 64. 13222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project In case native saturated arithmetic is not available, overflows 13232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project can be prevented by replacing the above #define by 13242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project #define SHIFT_BEFORE_SQUARE ((8 - OVRFLW_BITS) / 2) 13252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project which will result in slightly reduced accuracy. 13262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 13272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 13292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Estimates the mean energy of each filter-bank channel for the 13302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project duration of the current envelope 13312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function is used when interpolFreq is true. 13332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 13342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ 13352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */ 13362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, /*!< Begin of the SBR frequency range */ 13372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int highSubband, /*!< High end of the SBR frequency range */ 13382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int start_pos, /*!< First QMF-slot of current envelope */ 13392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int next_pos, /*!< Last QMF-slot of current envelope + 1 */ 13402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR frameExp, /*!< Common exponent for all input samples */ 13412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */ 13422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *nrgEst_e ) /*!< Exponent of resulting Energy */ 13432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 13442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL invWidth; 13452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR preShift; 13462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR shift; 13472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sum; 13482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k,l; 13492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Divide by width of envelope later: */ 13512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos)); 13522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The common exponent needs to be doubled because all mantissas are squared: */ 13532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project frameExp = frameExp << 1; 13542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=lowSubband; k<highSubband; k++) { 13562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL bufferReal[(((1024)/(32))+(6))]; 13572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL bufferImag[(((1024)/(32))+(6))]; 13582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL maxVal = FL2FX_DBL(0.0f); 13592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (analysBufferImag!=NULL) 13612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 13622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos;l<next_pos;l++) 13632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 13642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bufferImag[l] = analysBufferImag[l][k]; 13652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal |= (FIXP_DBL)((LONG)(bufferImag[l])^((LONG)bufferImag[l]>>(DFRACT_BITS-1))); 13662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bufferReal[l] = analysBufferReal[l][k]; 13672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal |= (FIXP_DBL)((LONG)(bufferReal[l])^((LONG)bufferReal[l]>>(DFRACT_BITS-1))); 13682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 13712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 13722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos;l<next_pos;l++) 13732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 13742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bufferReal[l] = analysBufferReal[l][k]; 13752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal |= (FIXP_DBL)((LONG)(bufferReal[l])^((LONG)bufferReal[l]>>(DFRACT_BITS-1))); 13762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (maxVal!=FL2FXCONST_DBL(0.f)) { 13802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* If the accu does not provide enough overflow bits, we cannot 13832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift the samples up to the limit. 13842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Instead, keep up to 3 free bits in each sample, i.e. up to 13852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6 bits after calculation of square. 13862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Please note the comment on saturated arithmetic above! 13872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 13882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL accu = FL2FXCONST_DBL(0.0f); 13892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project preShift = CntLeadingZeros(maxVal)-1; 13902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project preShift -= SHIFT_BEFORE_SQUARE; 13912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (preShift>=0) { 13932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (analysBufferImag!=NULL) { 13942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 13952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp1 = bufferReal[l] << (int)preShift; 13962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp2 = bufferImag[l] << (int)preShift; 13972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu = fPow2AddDiv2(accu, temp1); 13982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu = fPow2AddDiv2(accu, temp2); 13992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else 14012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 14022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 14032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp = bufferReal[l] << (int)preShift; 14042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu = fPow2AddDiv2(accu, temp); 14052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { /* if negative shift value */ 14092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int negpreShift = -preShift; 14102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (analysBufferImag!=NULL) { 14112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 14122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp1 = bufferReal[l] >> (int)negpreShift; 14132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp2 = bufferImag[l] >> (int)negpreShift; 14142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu = fPow2AddDiv2(accu, temp1); 14152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu = fPow2AddDiv2(accu, temp2); 14162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else 14182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 14192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 14202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp = bufferReal[l] >> (int)negpreShift; 14212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu = fPow2AddDiv2(accu, temp); 14222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu <<= 1; 14262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Convert double precision to Mantissa/Exponent: */ 14282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = fNorm(accu); 14292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum = accu << (int)shift; 14302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Divide by width of envelope and apply frame scale: */ 14322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst++ = fMult(sum, invWidth); 14332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift += 2 * preShift; 14342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (analysBufferImag!=NULL) 14352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst_e++ = frameExp - shift; 14362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 14372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst_e++ = frameExp - shift + 1; /* +1 due to missing imag. part */ 14382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } /* maxVal!=0 */ 14392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 14402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Prevent a zero-mantissa-number from being misinterpreted 14422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project due to its exponent. */ 14432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst++ = FL2FXCONST_DBL(0.0f); 14442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst_e++ = 0; 14452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 14482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 14502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Estimates the mean energy of each Scale factor band for the 14512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project duration of the current envelope. 14522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function is used when interpolFreq is false. 14542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 14552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ 14562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */ 14572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int nSfb, /*!< Number of scale factor bands */ 14582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *freqBandTable, /*!< First Subband for each Sfb */ 14592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int start_pos, /*!< First QMF-slot of current envelope */ 14602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int next_pos, /*!< Last QMF-slot of current envelope + 1 */ 14612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR input_e, /*!< Common exponent for all input samples */ 14622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */ 14632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *nrgEst_e ) /*!< Exponent of resulting Energy */ 14642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 14652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL invWidth; 14662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp; 14672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR preShift; 14682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR shift, sum_e; 14692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sum; 14702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int j,k,l,li,ui; 14722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sumAll, sumLine; /* Single precision would be sufficient, 14732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project but overflow bits are required for accumulation */ 14742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Divide by width of envelope later: */ 14762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos)); 14772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The common exponent needs to be doubled because all mantissas are squared: */ 14782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project input_e = input_e << 1; 14792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(j=0; j<nSfb; j++) { 14812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project li = freqBandTable[j]; 14822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ui = freqBandTable[j+1]; 14832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL maxVal = maxSubbandSample( analysBufferReal, 14852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project analysBufferImag, 14862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project li, 14872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ui, 14882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project start_pos, 14892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project next_pos ); 14902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (maxVal!=FL2FXCONST_DBL(0.f)) { 14922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project preShift = CntLeadingZeros(maxVal)-1; 14942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* If the accu does not provide enough overflow bits, we cannot 14962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift the samples up to the limit. 14972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Instead, keep up to 3 free bits in each sample, i.e. up to 14982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6 bits after calculation of square. 14992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Please note the comment on saturated arithmetic above! 15002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 15012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project preShift -= SHIFT_BEFORE_SQUARE; 15022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumAll = FL2FXCONST_DBL(0.0f); 15042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=li; k<ui; k++) { 15072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine = FL2FXCONST_DBL(0.0f); 15092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (analysBufferImag!=NULL) { 15112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (preShift>=0) { 15122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 15132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = analysBufferReal[l][k] << (int)preShift; 15142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine += fPow2Div2(temp); 15152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = analysBufferImag[l][k] << (int)preShift; 15162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine += fPow2Div2(temp); 15172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 15202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 15212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = analysBufferReal[l][k] >> -(int)preShift; 15222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine += fPow2Div2(temp); 15232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = analysBufferImag[l][k] >> -(int)preShift; 15242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine += fPow2Div2(temp); 15252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else 15282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 15292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (preShift>=0) { 15302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 15312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = analysBufferReal[l][k] << (int)preShift; 15322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine += fPow2Div2(temp); 15332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 15352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 15362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = analysBufferReal[l][k] >> -(int)preShift; 15372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine += fPow2Div2(temp); 15382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The number of QMF-channels per SBR bands may be up to 15. 15432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Shift right to avoid overflows in sum over all channels. */ 15442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine = sumLine >> (4-1); 15452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumAll += sumLine; 15462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Convert double precision to Mantissa/Exponent: */ 15492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = fNorm(sumAll); 15502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum = sumAll << (int)shift; 15512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Divide by width of envelope: */ 15532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum = fMult(sum,invWidth); 15542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Divide by width of Sfb: */ 15562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum = fMult(sum, FX_DBL2FX_SGL(GetInvInt(ui-li))); 15572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Set all Subband energies in the Sfb to the average energy: */ 15592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (analysBufferImag!=NULL) 15602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum_e = input_e + 4 - shift; /* -4 to compensate right-shift */ 15612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 15622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum_e = input_e + 4 + 1 - shift; /* -4 to compensate right-shift; +1 due to missing imag. part */ 15632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum_e -= 2 * preShift; 15652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } /* maxVal!=0 */ 15662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 15672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Prevent a zero-mantissa-number from being misinterpreted 15692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project due to its exponent. */ 15702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum = FL2FXCONST_DBL(0.0f); 15712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum_e = 0; 15722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=li; k<ui; k++) 15752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 15762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst++ = sum; 15772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst_e++ = sum_e; 15782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 15812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 15842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Calculate gain, noise, and additional sine level for one subband. 15852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The resulting energy gain is given by mantissa and exponent. 15872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 15882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */ 15892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */ 15902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ENV_CALC_NRGS* nrgs, 15912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int i, 15922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmpNoise, /*!< Relative noise level */ 15932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR tmpNoise_e, /*!< Relative noise level (exponent) */ 15942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR sinePresentFlag, /*!< Indicates if sine is present on band */ 15952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR sineMapped, /*!< Indicates if sine must be added */ 15962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noNoiseFlag) /*!< Flag to suppress noise addition */ 15972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 15982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL nrgEst = nrgs->nrgEst[i]; /*!< Energy in transposed signal */ 15992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgEst_e = nrgs->nrgEst_e[i]; /*!< Energy in transposed signal (exponent) */ 16002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *ptrNrgGain = &nrgs->nrgGain[i]; /*!< Resulting energy gain */ 16012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *ptrNrgGain_e = &nrgs->nrgGain_e[i]; /*!< Resulting energy gain (exponent) */ 16022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *ptrNoiseLevel = &nrgs->noiseLevel[i]; /*!< Resulting absolute noise energy */ 16032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *ptrNoiseLevel_e = &nrgs->noiseLevel_e[i]; /*!< Resulting absolute noise energy (exponent) */ 16042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *ptrNrgSine = &nrgs->nrgSine[i]; /*!< Additional sine energy */ 16052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *ptrNrgSine_e = &nrgs->nrgSine_e[i]; /*!< Additional sine energy (exponent) */ 16062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL a, b, c; 16082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR a_e, b_e, c_e; 16092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 16112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This addition of 1 prevents divisions by zero in the reference code. 16122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project For very small energies in nrgEst, it prevents the gains from becoming 16132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project very high which could cause some trouble due to the smoothing. 16142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 16152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b_e = (int)(nrgEst_e - 1); 16162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (b_e>=0) { 16172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgEst = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e+1,DFRACT_BITS-1)) + (nrgEst >> 1); 16182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgEst_e += 1; /* shift by 1 bit to avoid overflow */ 16192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 16212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgEst = (nrgEst >> (INT)(fixMin(-b_e+1,DFRACT_BITS-1))) + (FL2FXCONST_DBL(0.5f) >> 1); 16222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgEst_e = 2; /* shift by 1 bit to avoid overflow */ 16232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* A = NrgRef * TmpNoise */ 16262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project a = fMult(nrgRef,tmpNoise); 16272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project a_e = nrgRef_e + tmpNoise_e; 16282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* B = 1 + TmpNoise */ 16302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b_e = (int)(tmpNoise_e - 1); 16312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (b_e>=0) { 16322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e+1,DFRACT_BITS-1)) + (tmpNoise >> 1); 16332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b_e = tmpNoise_e + 1; /* shift by 1 bit to avoid overflow */ 16342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 16352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b = (tmpNoise >> (INT)(fixMin(-b_e+1,DFRACT_BITS-1))) + (FL2FXCONST_DBL(0.5f) >> 1); 16362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b_e = 2; /* shift by 1 bit to avoid overflow */ 16372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */ 16402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp( a, a_e, 16412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b, b_e, 16422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ptrNoiseLevel, ptrNoiseLevel_e); 16432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (sinePresentFlag) { 16452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* C = (1 + TmpNoise) * NrgEst */ 16472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project c = fMult(b,nrgEst); 16482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project c_e = b_e + nrgEst_e; 16492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */ 16512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp( a, a_e, 16522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project c, c_e, 16532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ptrNrgGain, ptrNrgGain_e); 16542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (sineMapped) { 16562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* sineLevel = nrgRef/ (1 + TmpNoise) */ 16582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp( nrgRef, nrgRef_e, 16592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b, b_e, 16602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ptrNrgSine, ptrNrgSine_e); 16612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 16642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (noNoiseFlag) { 16652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* B = NrgEst */ 16662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b = nrgEst; 16672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b_e = nrgEst_e; 16682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 16702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* B = NrgEst * (1 + TmpNoise) */ 16712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b = fMult(b,nrgEst); 16722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b_e = b_e + nrgEst_e; 16732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* gain = nrgRef / B */ 16772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp( nrgRef, nrgRef_e, 16782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b, b_e, 16792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ptrNrgGain, ptrNrgGain_e); 16802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 16822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 16852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Calculate "average gain" for the specified subband range. 16862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This is rather a gain of the average magnitude than the average 16882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project of gains! 16892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The result is used as a relative limit for all gains within the 16902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project current "limiter band" (a certain frequency range). 16912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 16922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs, 16932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, /*!< Begin of the limiter band */ 16942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int highSubband, /*!< High end of the limiter band */ 16952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *ptrSumRef, 16962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *ptrSumRef_e, 16972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *ptrAvgGain, /*!< Resulting overall gain (mantissa) */ 16982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *ptrAvgGain_e) /*!< Resulting overall gain (exponent) */ 16992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 17002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *nrgRef = nrgs->nrgRef; /*!< Reference Energy according to envelope data */ 17012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *nrgRef_e = nrgs->nrgRef_e; /*!< Reference Energy according to envelope data (exponent) */ 17022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< Energy in transposed signal */ 17032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *nrgEst_e = nrgs->nrgEst_e; /*!< Energy in transposed signal (exponent) */ 17042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sumRef = 1; 17062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sumEst = 1; 17072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR sumRef_e = -FRACT_BITS; 17082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR sumEst_e = -FRACT_BITS; 17092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k; 17102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=lowSubband; k<highSubband; k++){ 17122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add nrgRef[k] to sumRef: */ 17132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp( sumRef, sumRef_e, 17142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgRef[k], nrgRef_e[k], 17152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &sumRef, &sumRef_e ); 17162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add nrgEst[k] to sumEst: */ 17182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp( sumEst, sumEst_e, 17192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgEst[k], nrgEst_e[k], 17202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &sumEst, &sumEst_e ); 17212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 17222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp(sumRef, sumRef_e, 17242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumEst, sumEst_e, 17252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ptrAvgGain, ptrAvgGain_e); 17262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrSumRef = sumRef; 17282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrSumRef_e = sumRef_e; 17292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 17302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 17332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Amplify one timeslot of the signal with the calculated gains 17342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and add the noisefloor. 17352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 17362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */ 17382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ENV_CALC_NRGS* nrgs, 17392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *ptrHarmIndex, /*!< Harmonic index */ 17402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ 17412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noSubbands, /*!< Number of QMF subbands */ 17422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int scale_change, /*!< Number of bits to shift adjusted samples */ 17432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noNoiseFlag, /*!< Flag to suppress noise addition */ 17442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int *ptrPhaseIndex, /*!< Start index to random number array */ 17452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int fCldfb) /*!< CLDFB 80 flag */ 17462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 17472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */ 17482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */ 17492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */ 17502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k; 17522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int index = *ptrPhaseIndex; 17532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR harmIndex = *ptrHarmIndex; 17542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR freqInvFlag = (lowSubband & 1); 17552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev; 17562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int tone_count = 0; 17572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int sineSign = 1; 17582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project #define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f*0.00815f)) 17602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project #define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f*0.16773f)) 17612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 17632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project First pass for k=0 pulled out of the loop: 17642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 17652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index = (index + 1) & (SBR_NF_NO_RANDOM_VAL - 1); 17672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 17692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The next multiplication constitutes the actual envelope adjustment 17702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project of the signal and should be carried out with full accuracy 17712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (supplying #FRACT_BITS valid bits). 17722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 17732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal = fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change); 17742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineLevel = *pSineLevel++; 17752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f); 17762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (sineLevel!=FL2FXCONST_DBL(0.0f)) tone_count++; 17782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else if (!noNoiseFlag) 17802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add noisefloor to the amplified signal */ 17812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4); 17822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (fCldfb) { 17842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!(harmIndex&0x1)) { 17862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 0,2 */ 17872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += (harmIndex&0x2) ? -sineLevel : sineLevel; 17882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 17892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 17902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 17912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 1,3 in combination with freqInvFlag */ 17922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int shift = (int) (scale_change+1); 17932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = (shift>=0) ? fixMin(DFRACT_BITS-1,shift) : fixMax(-(DFRACT_BITS-1),shift); 17942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp1 = scaleValue( fMultDiv2(C1_CLDFB, sineLevel), -shift ); 17962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp2 = fMultDiv2(C1_CLDFB, sineLevelNext); 17982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* save switch and compare operations and reduce to XOR statement */ 18012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( ((harmIndex>>1)&0x1)^freqInvFlag) { 18022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *(ptrReal-1) += tmp1; 18032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal -= tmp2; 18042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 18052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *(ptrReal-1) -= tmp1; 18062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += tmp2; 18072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 18092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project freqInvFlag = !freqInvFlag; 18102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else 18132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 18142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!(harmIndex&0x1)) { 18152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 0,2 */ 18162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += (harmIndex&0x2) ? -sineLevel : sineLevel; 18172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 18182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 18202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 1,3 in combination with freqInvFlag */ 18212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int shift = (int) (scale_change+1); 18222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = (shift>=0) ? fixMin(DFRACT_BITS-1,shift) : fixMax(-(DFRACT_BITS-1),shift); 18232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp1 = (shift>=0) ? ( fMultDiv2(C1, sineLevel) >> shift ) 18252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project : ( fMultDiv2(C1, sineLevel) << (-shift) ); 18262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp2 = fMultDiv2(C1, sineLevelNext); 18272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* save switch and compare operations and reduce to XOR statement */ 18302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( ((harmIndex>>1)&0x1)^freqInvFlag) { 18312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *(ptrReal-1) += tmp1; 18322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal -= tmp2; 18332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 18342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *(ptrReal-1) -= tmp1; 18352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += tmp2; 18362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 18382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project freqInvFlag = !freqInvFlag; 18392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNoiseLevel++; 18432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( noSubbands > 2 ) { 18452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!(harmIndex&0x1)) { 18462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 0,2 */ 18472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(!harmIndex) 18482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 18492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineSign = 0; 18502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=noSubbands-2; k!=0; k--) { 18532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sinelevel = *pSineLevel++; 18542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index++; 18552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (((signalReal = (sineSign ? -sinelevel : sinelevel)) == FL2FXCONST_DBL(0.0f)) && !noNoiseFlag) 18562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 18572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add noisefloor to the amplified signal */ 18582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index &= (SBR_NF_NO_RANDOM_VAL - 1); 18592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4); 18602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The next multiplication constitutes the actual envelope adjustment of the signal. */ 18632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change); 18642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNoiseLevel++; 18662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 18672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } /* for ... */ 18682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 18702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 1,3 in combination with freqInvFlag */ 18712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (harmIndex==1) freqInvFlag = !freqInvFlag; 18722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=noSubbands-2; k!=0; k--) { 18742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index++; 18752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The next multiplication constitutes the actual envelope adjustment of the signal. */ 18762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal = fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change); 18772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (*pSineLevel++!=FL2FXCONST_DBL(0.0f)) tone_count++; 18792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else if (!noNoiseFlag) { 18802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add noisefloor to the amplified signal */ 18812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index &= (SBR_NF_NO_RANDOM_VAL - 1); 18822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4); 18832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNoiseLevel++; 18862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (tone_count <= 16) { 18882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL addSine = fMultDiv2((pSineLevel[-2] - pSineLevel[0]), C1); 18892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += (freqInvFlag) ? (-addSine) : (addSine); 18902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 18932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project freqInvFlag = !freqInvFlag; 18942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } /* for ... */ 18952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (noSubbands > -1) { 18992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index++; 19002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The next multiplication constitutes the actual envelope adjustment of the signal. */ 19012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal = fMultDiv2(*ptrReal,*pGain) << ((int)scale_change); 19022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineLevelPrev = fMultDiv2(pSineLevel[-1],FL2FX_SGL(0.0163f)); 19032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineLevel = pSineLevel[0]; 19042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (pSineLevel[0]!=FL2FXCONST_DBL(0.0f)) tone_count++; 19062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else if (!noNoiseFlag) { 19072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add noisefloor to the amplified signal */ 19082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index &= (SBR_NF_NO_RANDOM_VAL - 1); 19092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal = signalReal + (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4); 19102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!(harmIndex&0x1)) { 19132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 0,2 */ 19142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal = signalReal + ( (sineSign) ? -sineLevel : sineLevel); 19152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 19172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 1,3 in combination with freqInvFlag */ 19182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(tone_count <= 16){ 19192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (freqInvFlag) { 19202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal - sineLevelPrev; 19212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (noSubbands + lowSubband < 63) 19222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal = *ptrReal + fMultDiv2(C1, sineLevel); 19232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 19252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal + sineLevelPrev; 19262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (noSubbands + lowSubband < 63) 19272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal = *ptrReal - fMultDiv2(C1, sineLevel); 19282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else *ptrReal = signalReal; 19312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrHarmIndex = (harmIndex + 1) & 3; 19342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1); 19352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 19362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid adjustTimeSlotHQ(FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */ 19372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */ 19382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, 19392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ENV_CALC_NRGS* nrgs, 19402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ 19412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noSubbands, /*!< Number of QMF subbands */ 19422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int scale_change, /*!< Number of bits to shift adjusted samples */ 19432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL smooth_ratio, /*!< Impact of last envelope */ 19442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noNoiseFlag, /*!< Start index to random number array */ 19452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */ 19462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 19472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */ 19492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *RESTRICT noiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */ 19502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */ 19512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *RESTRICT filtBuffer = h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */ 19532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *RESTRICT filtBufferNoise = h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */ 19542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *RESTRICT ptrHarmIndex =&h_sbr_cal_env->harmIndex; /*!< Harmonic index */ 19552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int *RESTRICT ptrPhaseIndex =&h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */ 19562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k; 19582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL signalReal, signalImag; 19592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL noiseReal, noiseImag; 19602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL smoothedGain, smoothedNoise; 19612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL direct_ratio = /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio; 19622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int index = *ptrPhaseIndex; 19632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR harmIndex = *ptrHarmIndex; 19642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project register int freqInvFlag = (lowSubband & 1); 19652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sineLevel; 19662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int shift; 19672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrPhaseIndex = (index+noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1); 19692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrHarmIndex = (harmIndex + 1) & 3; 19702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 19722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Possible optimization: 19732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smooth_ratio and harmIndex stay constant during the loop. 19742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project It might be faster to include a separate loop in each path. 19752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the check for smooth_ratio is now outside the loop and the workload 19772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project of the whole function decreased by about 20 % 19782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 19792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBufferNoiseShift += 1; /* due to later use of fMultDiv2 instead of fMult */ 19812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (filtBufferNoiseShift<0) 19822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = fixMin(DFRACT_BITS-1,-filtBufferNoiseShift); 19832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 19842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = fixMin(DFRACT_BITS-1, filtBufferNoiseShift); 19852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (smooth_ratio > FL2FXCONST_SGL(0.0f)) { 19872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) { 19892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 19902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Smoothing: The old envelope has been bufferd and a certain ratio 19912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project of the old gains and noise levels is used. 19922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 19932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smoothedGain = fMult(smooth_ratio,filtBuffer[k]) + 19952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fMult(direct_ratio,gain[k]); 19962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (filtBufferNoiseShift<0) { 19982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smoothedNoise = (fMultDiv2(smooth_ratio,filtBufferNoise[k])>>shift) + 19992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fMult(direct_ratio,noiseLevel[k]); 20002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 20022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smoothedNoise = (fMultDiv2(smooth_ratio,filtBufferNoise[k])<<shift) + 20032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fMult(direct_ratio,noiseLevel[k]); 20042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 20072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The next 2 multiplications constitute the actual envelope adjustment 20082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project of the signal and should be carried out with full accuracy 20092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (supplying #DFRACT_BITS valid bits). 20102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 20112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal = fMultDiv2(*ptrReal,smoothedGain)<<((int)scale_change); 20122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag = fMultDiv2(*ptrImag,smoothedGain)<<((int)scale_change); 20132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index++; 20152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (pSineLevel[k] != FL2FXCONST_DBL(0.0f)) { 20172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineLevel = pSineLevel[k]; 20182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch(harmIndex) { 20202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 0: 20212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = (signalReal + sineLevel); 20222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag); 20232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 20242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 2: 20252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = (signalReal - sineLevel); 20262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag); 20272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 20282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 1: 20292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = (signalReal); 20302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (freqInvFlag) 20312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag - sineLevel); 20322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 20332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag + sineLevel); 20342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 20352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 3: 20362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 20372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (freqInvFlag) 20382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag + sineLevel); 20392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 20402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag - sineLevel); 20412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 20422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 20452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (noNoiseFlag) { 20462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Just the amplified signal is saved */ 20472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = (signalReal); 20482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag); 20492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 20512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add noisefloor to the amplified signal */ 20522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index &= (SBR_NF_NO_RANDOM_VAL - 1); 20532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noiseReal = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise)<<4; 20542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noiseImag = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise)<<4; 20552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = (signalReal + noiseReal); 20562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag + noiseImag); 20572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project freqInvFlag ^= 1; 20602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 20642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 20652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) 20662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 20672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smoothedGain = gain[k]; 20682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change; 20692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change; 20702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index++; 20722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ((sineLevel = pSineLevel[k]) != FL2FXCONST_DBL(0.0f)) 20742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 20752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch (harmIndex) 20762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 20772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 0: 20782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += sineLevel; 20792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 20802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 1: 20812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (freqInvFlag) 20822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag -= sineLevel; 20832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 20842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag += sineLevel; 20852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 20862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 2: 20872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal -= sineLevel; 20882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 20892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 3: 20902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (freqInvFlag) 20912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag += sineLevel; 20922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 20932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag -= sineLevel; 20942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 20952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 20982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 20992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (noNoiseFlag == 0) 21002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 21012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add noisefloor to the amplified signal */ 21022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smoothedNoise = noiseLevel[k]; 21032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index &= (SBR_NF_NO_RANDOM_VAL - 1); 21042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noiseReal = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise); 21052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noiseImag = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise); 21062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += noiseReal<<4; 21072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag += noiseImag<<4; 21082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 21112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = signalImag; 21122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project freqInvFlag ^= 1; 21142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 21172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 21202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Reset limiter bands. 21212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Build frequency band table for the gain limiter dependent on 21232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the previously generated transposer patch areas. 21242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \return SBRDEC_OK if ok, SBRDEC_UNSUPPORTED_CONFIG on error 21262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 21272228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectSBR_ERROR 21282228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QMF channels */ 21292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *noLimiterBands, /*!< Resulting number of limiter band */ 21302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *freqBandTable, /*!< Table with possible band borders */ 21312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noFreqBands, /*!< Number of bands in freqBandTable */ 21322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const PATCH_PARAM *patchParam, /*!< Transposer patch parameters */ 21332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noPatches, /*!< Number of transposer patches */ 21342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int limiterBands) /*!< Selected 'band density' from bitstream */ 21352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 21362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int i, k, isPatchBorder[2], loLimIndex, hiLimIndex, tempNoLim, nBands; 21372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1]; 21382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int patchBorders[MAX_NUM_PATCHES + 1]; 21392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int kx, k2; 21402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp; 21412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband = freqBandTable[0]; 21432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int highSubband = freqBandTable[noFreqBands]; 21442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 1 limiter band. */ 21462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(limiterBands == 0) { 21472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project limiterBandTable[0] = 0; 21482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project limiterBandTable[1] = highSubband - lowSubband; 21492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nBands = 1; 21502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 21512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (i = 0; i < noPatches; i++) { 21522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project patchBorders[i] = patchParam[i].guardStartBand - lowSubband; 21532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project patchBorders[i] = highSubband - lowSubband; 21552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */ 21572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = 0; k <= noFreqBands; k++) { 21582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project workLimiterBandTable[k] = freqBandTable[k] - lowSubband; 21592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = 1; k < noPatches; k++) { 21612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project workLimiterBandTable[noFreqBands + k] = patchBorders[k]; 21622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tempNoLim = nBands = noFreqBands + noPatches - 1; 21652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shellsort(workLimiterBandTable, tempNoLim + 1); 21662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project loLimIndex = 0; 21682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hiLimIndex = 1; 21692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project while (hiLimIndex <= tempNoLim) { 21722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project k2 = workLimiterBandTable[hiLimIndex] + lowSubband; 21732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project kx = workLimiterBandTable[loLimIndex] + lowSubband; 21742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = FX_SGL2FX_DBL(FDK_getNumOctavesDiv8(kx,k2)); /* Number of octaves */ 21762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = fMult(temp, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[limiterBands]); 21772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (temp < FL2FXCONST_DBL (0.49f)>>5) { 21792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (workLimiterBandTable[hiLimIndex] == workLimiterBandTable[loLimIndex]) { 21802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project workLimiterBandTable[hiLimIndex] = highSubband; 21812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nBands--; 21822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hiLimIndex++; 21832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project continue; 21842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isPatchBorder[0] = isPatchBorder[1] = 0; 21862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = 0; k <= noPatches; k++) { 21872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (workLimiterBandTable[hiLimIndex] == patchBorders[k]) { 21882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isPatchBorder[1] = 1; 21892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 21902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!isPatchBorder[1]) { 21932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project workLimiterBandTable[hiLimIndex] = highSubband; 21942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nBands--; 21952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hiLimIndex++; 21962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project continue; 21972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = 0; k <= noPatches; k++) { 21992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (workLimiterBandTable[loLimIndex] == patchBorders[k]) { 22002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isPatchBorder[0] = 1; 22012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 22022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!isPatchBorder[0]) { 22052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project workLimiterBandTable[loLimIndex] = highSubband; 22062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nBands--; 22072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project loLimIndex = hiLimIndex; 22102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hiLimIndex++; 22112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shellsort(workLimiterBandTable, tempNoLim + 1); 22142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Test if algorithm exceeded maximum allowed limiterbands */ 22162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if( nBands > MAX_NUM_LIMITERS || nBands <= 0) { 22172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return SBRDEC_UNSUPPORTED_CONFIG; 22182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Copy limiterbands from working buffer into final destination */ 22212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = 0; k <= nBands; k++) { 22222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project limiterBandTable[k] = workLimiterBandTable[k]; 22232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *noLimiterBands = nBands; 22262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return SBRDEC_OK; 22282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 22292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2230