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 5203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi� Copyright 1995 - 2015 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 154203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic 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 160203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic 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 168203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic 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 177203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic 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 183203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic 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 191203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic void adjustTimeSlot_EldGrid(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, 199203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int scale_diff_low); 200203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 201203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic void adjustTimeSlotLC(FIXP_DBL *ptrReal, 202203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi ENV_CALC_NRGS* nrgs, 203203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi UCHAR *ptrHarmIndex, 204203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int lowSubbands, 205203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int noSubbands, 206203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int scale_change, 207203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int noNoiseFlag, 208203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int *ptrPhaseIndex); 209203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic void adjustTimeSlotHQ(FIXP_DBL *ptrReal, 2102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *ptrImag, 2112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, 2122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ENV_CALC_NRGS* nrgs, 2132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubbands, 2142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noSubbands, 2152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int scale_change, 2162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL smooth_ratio, 2172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noNoiseFlag, 2182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int filtBufferNoiseShift); 2192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 2222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Map sine flags from bitstream to QMF bands 2232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The bitstream carries only 1 sine flag per band and frame. 2252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function maps every sine flag from the bitstream to a specific QMF subband 2262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and to a specific envelope where the sine shall start. 2272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The result is stored in the vector sineMapped which contains one entry per 2282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project QMF subband. The value of an entry specifies the envelope where a sine 2292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shall start. A value of #MAX_ENVELOPES indicates that no sine is present 2302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project in the subband. 2312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The missing harmonics flags from the previous frame (harmFlagsPrev) determine 2322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if a sine starts at the beginning of the frame or at the transient position. 2332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Additionally, the flags in harmFlagsPrev are being updated by this function 2342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for the next frame. 2352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 236203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */ 2372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int nSfb, /*!< Number of bands in the table */ 2382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *addHarmonics, /*!< vector with 1 flag per sfb */ 2392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int *harmFlagsPrev, /*!< Packed 'addHarmonics' */ 2402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int tranEnv, /*!< Transient position */ 2412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *sineMapped) /*!< Resulting vector of sine start positions for each QMF band */ 2422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 2442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int i; 2452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband2 = freqBandTable[0]<<1; 2462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int bitcount = 0; 2472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int oldflags = *harmFlagsPrev; 2482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int newflags = 0; 2492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 2512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Format of harmFlagsPrev: 2522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project first word = flags for highest 16 sfb bands in use 2542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project second word = flags for next lower 16 sfb bands (if present) 2552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project third word = flags for lowest 16 sfb bands (if present) 2562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Up to MAX_FREQ_COEFFS sfb bands can be flagged for a sign. 2582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The lowest bit of the first word corresponds to the _highest_ sfb band in use. 2592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This is ensures that each flag is mapped to the same QMF band even after a 2602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project change of the crossover-frequency. 2612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 2622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Reset the output vector first */ 2652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemset(sineMapped, MAX_ENVELOPES,MAX_FREQ_COEFFS); /* MAX_ENVELOPES means 'no sine' */ 2662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project freqBandTable += nSfb; 2682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project addHarmonics += nSfb-1; 2692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (i=nSfb; i!=0; i--) { 2712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int ui = *freqBandTable--; /* Upper limit of the current scale factor band. */ 2722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int li = *freqBandTable; /* Lower limit of the current scale factor band. */ 2732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( *addHarmonics-- ) { /* There is a sine in this band */ 2752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project unsigned int mask = 1 << bitcount; 2772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project newflags |= mask; /* Set flag */ 2782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 2802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project If there was a sine in the last frame, let it continue from the first envelope on 2812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else start at the transient position. 2822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 2832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineMapped[(ui+li-lowSubband2) >> 1] = ( oldflags & mask ) ? 0 : tranEnv; 2842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ((++bitcount == 16) || i==1) { 2872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bitcount = 0; 2882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *harmFlagsPrev++ = newflags; 2892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project oldflags = *harmFlagsPrev; /* Fetch 16 of the old flags */ 2902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project newflags = 0; 2912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 2932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 2942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 2972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Reduce gain-adjustment induced aliasing for real valued filterbank. 2982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 2992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*static*/ void 3002228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectaliasingReduction(FIXP_DBL* degreeAlias, /*!< estimated aliasing for each QMF channel */ 3012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ENV_CALC_NRGS* nrgs, 3022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int* useAliasReduction, /*!< synthetic sine engergy for each subband, used as flag */ 3032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noSubbands) /*!< number of QMF channels to process */ 3042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 3052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL* nrgGain = nrgs->nrgGain; /*!< subband gains to be modified */ 3062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR* nrgGain_e = nrgs->nrgGain_e; /*!< subband gains to be modified (exponents) */ 3072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL* nrgEst = nrgs->nrgEst; /*!< subband energy before amplification */ 3082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR* nrgEst_e = nrgs->nrgEst_e; /*!< subband energy before amplification (exponents) */ 3092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int grouping = 0, index = 0, noGroups, k; 3102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int groupVector[MAX_FREQ_COEFFS]; 3112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Calculate grouping*/ 3132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = 0; k < noSubbands-1; k++ ){ 3142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( (degreeAlias[k + 1] != FL2FXCONST_DBL(0.0f)) && useAliasReduction[k] ) { 3152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(grouping==0){ 3162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project groupVector[index++] = k; 3172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project grouping = 1; 3182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else{ 3202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(groupVector[index-1] + 3 == k){ 3212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project groupVector[index++] = k + 1; 3222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project grouping = 0; 3232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else{ 3272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(grouping){ 3282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(useAliasReduction[k]) 3292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project groupVector[index++] = k + 1; 3302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 3312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project groupVector[index++] = k; 3322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project grouping = 0; 3332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(grouping){ 3382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project groupVector[index++] = noSubbands; 3392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noGroups = index >> 1; 3412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /*Calculate new gain*/ 3442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (int group = 0; group < noGroups; group ++) { 3452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL nrgOrig = FL2FXCONST_DBL(0.0f); /* Original signal energy in current group of bands */ 3462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgOrig_e = 0; 3472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL nrgAmp = FL2FXCONST_DBL(0.0f); /* Amplified signal energy in group (using current gains) */ 3482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgAmp_e = 0; 3492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL nrgMod = FL2FXCONST_DBL(0.0f); /* Signal energy in group when applying modified gains */ 3502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgMod_e = 0; 3512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL groupGain; /* Total energy gain in group */ 3522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR groupGain_e; 3532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL compensation; /* Compensation factor for the energy change when applying modified gains */ 3542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR compensation_e; 3552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int startGroup = groupVector[2*group]; 3572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int stopGroup = groupVector[2*group+1]; 3582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Calculate total energy in group before and after amplification with current gains: */ 3602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k = startGroup; k < stopGroup; k++){ 3612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Get original band energy */ 3622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp = nrgEst[k]; 3632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR tmp_e = nrgEst_e[k]; 3642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp(tmp, tmp_e, nrgOrig, nrgOrig_e, &nrgOrig, &nrgOrig_e); 3662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Multiply band energy with current gain */ 3682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmp = fMult(tmp,nrgGain[k]); 3692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmp_e = tmp_e + nrgGain_e[k]; 3702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp(tmp, tmp_e, nrgAmp, nrgAmp_e, &nrgAmp, &nrgAmp_e); 3722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Calculate total energy gain in group */ 3752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp(nrgAmp, nrgAmp_e, 3762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgOrig, nrgOrig_e, 3772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &groupGain, &groupGain_e); 3782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k = startGroup; k < stopGroup; k++){ 3802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp; 3812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR tmp_e; 3822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL alpha = degreeAlias[k]; 3842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (k < noSubbands - 1) { 3852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (degreeAlias[k + 1] > alpha) 3862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project alpha = degreeAlias[k + 1]; 3872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 3882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Modify gain depending on the degree of aliasing */ 3902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp( fMult(alpha,groupGain), groupGain_e, 3912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fMult(/*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - alpha,nrgGain[k]), nrgGain_e[k], 3922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &nrgGain[k], &nrgGain_e[k] ); 3932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Apply modified gain to original energy */ 3952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmp = fMult(nrgGain[k],nrgEst[k]); 3962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmp_e = nrgGain_e[k] + nrgEst_e[k]; 3972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Accumulate energy with modified gains applied */ 3992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp( tmp, tmp_e, 4002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgMod, nrgMod_e, 4012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &nrgMod, &nrgMod_e ); 4022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 4032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Calculate compensation factor to retain the energy of the amplified signal */ 4052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp(nrgAmp, nrgAmp_e, 4062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgMod, nrgMod_e, 4072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &compensation, &compensation_e); 4082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Apply compensation factor to all gains of the group */ 4102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k = startGroup; k < stopGroup; k++){ 4112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgGain[k] = fMult(nrgGain[k],compensation); 4122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgGain_e[k] = nrgGain_e[k] + compensation_e; 4132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 4142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 4152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 4162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Convert headroom bits to exponent */ 4192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define SCALE2EXP(s) (15-(s)) 4202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define EXP2SCALE(e) (15-(e)) 4212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 4232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Apply spectral envelope to subband samples 4242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function is called from sbr_dec.cpp in each frame. 4262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project To enhance accuracy and due to the usage of tables for squareroots and 4282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project inverse, some calculations are performed with the operands being split 4292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project into mantissa and exponent. The variable names in the source code carry 4302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the suffixes <em>_m</em> and <em>_e</em> respectively. The control data 4312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project in #hFrameData containts envelope data which is represented by this format but 4322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project stored in single words. (See requantizeEnvelopeData() for details). This data 4332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project is unpacked within calculateSbrEnvelope() to follow the described suffix convention. 4342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The actual value (comparable to the corresponding float-variable in the 4362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project research-implementation) of a mantissa/exponent-pair can be calculated as 4372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \f$ value = value\_m * 2^{value\_e} \f$ 4392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project All energies and noise levels decoded from the bitstream suit for an 4412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project original signal magnitude of \f$\pm 32768 \f$ rather than \f$ \pm 1\f$. Therefore, 4422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the scale factor <em>hb_scale</em> passed into this function will be converted 4432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project to an 'input exponent' (#input_e), which fits the internal representation. 4442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Before the actual processing, an exponent #adj_e for resulting adjusted 4462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project samples is derived from the maximum reference energy. 4472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Then, for each envelope, the following steps are performed: 4492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \li Calculate energy in the signal to be adjusted. Depending on the the value of 4512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project #interpolFreq (interpolation mode), this is either done seperately 4522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for each QMF-subband or for each SBR-band. 4532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The resulting energies are stored in #nrgEst_m[#MAX_FREQ_COEFFS] (mantissas) 4542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and #nrgEst_e[#MAX_FREQ_COEFFS] (exponents). 4552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \li Calculate gain and noise level for each subband:<br> 4562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \f$ gain = \sqrt{ \frac{nrgRef}{nrgEst} \cdot (1 - noiseRatio) } 4572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \hspace{2cm} 4582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noise = \sqrt{ nrgRef \cdot noiseRatio } 4592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \f$<br> 4602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project where <em>noiseRatio</em> and <em>nrgRef</em> are extracted from the 4612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bitstream and <em>nrgEst</em> is the subband energy before adjustment. 4622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The resulting gains are stored in #nrgGain_m[#MAX_FREQ_COEFFS] 4632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (mantissas) and #nrgGain_e[#MAX_FREQ_COEFFS] (exponents), the noise levels 4642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project are stored in #noiseLevel_m[#MAX_FREQ_COEFFS] and #noiseLevel_e[#MAX_FREQ_COEFFS] 4652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (exponents). 4662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The sine levels are stored in #nrgSine_m[#MAX_FREQ_COEFFS] 4672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and #nrgSine_e[#MAX_FREQ_COEFFS]. 4682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \li Noise limiting: The gain for each subband is limited both absolutely 4692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and relatively compared to the total gain over all subbands. 4702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \li Boost gain: Calculate and apply boost factor for each limiter band 4712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project in order to compensate for the energy loss imposed by the limiting. 4722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \li Apply gains and add noise: The gains and noise levels are applied 4732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project to all timeslots of the current envelope. A short FIR-filter (length 4 4742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project QMF-timeslots) can be used to smooth the sudden change at the envelope borders. 4752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Each complex subband sample of the current timeslot is multiplied by the 4762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smoothed gain, then random noise with the calculated level is added. 4772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \note 4792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project To reduce the stack size, some of the local arrays could be located within 4802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the time output buffer. Of the 512 samples temporarily available there, 4812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project about half the size is already used by #SBR_FRAME_DATA. A pointer to the 4822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project remaining free memory could be supplied by an additional argument to calculateSbrEnvelope() 4832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project in sbr_dec: 4842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \par 4862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \code 4872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project calculateSbrEnvelope (&hSbrDec->sbrScaleFactor, 4882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &hSbrDec->SbrCalculateEnvelope, 4892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hHeaderData, 4902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFrameData, 4912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project QmfBufferReal, 4922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project QmfBufferImag, 4932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project timeOutPtr + sizeof(SBR_FRAME_DATA)/sizeof(Float) + 1); 4942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \endcode 4952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 4962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \par 4972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Within calculateSbrEnvelope(), some pointers could be defined instead of the arrays 4982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project #nrgRef_m, #nrgRef_e, #nrgEst_m, #nrgEst_e, #noiseLevel_m: 4992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \par 5012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \code 5022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fract* nrgRef_m = timeOutPtr; 5032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR* nrgRef_e = nrgRef_m + MAX_FREQ_COEFFS; 5042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fract* nrgEst_m = nrgRef_e + MAX_FREQ_COEFFS; 5052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR* nrgEst_e = nrgEst_m + MAX_FREQ_COEFFS; 5062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fract* noiseLevel_m = nrgEst_e + MAX_FREQ_COEFFS; 5072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \endcode 5082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project <br> 5102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 5112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid 5122228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectcalculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */ 5132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, /*!< Handle to struct filled by the create-function */ 5142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ 5152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */ 5162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL **analysBufferReal, /*!< Real part of subband samples to be processed */ 5172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL **analysBufferImag, /*!< Imag part of subband samples to be processed */ 5182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const int useLP, 5192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *degreeAlias, /*!< Estimated aliasing for each QMF channel */ 5202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const UINT flags, 5212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const int frameErrorFlag 5222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 5232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 5242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int c, i, j, envNoise = 0; 5252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR* borders = hFrameData->frameInfo.borders; 5262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL *noiseLevels = hFrameData->sbrNoiseFloorLevel; 5282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData; 5292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband = hFreq->lowSubband; 5312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int highSubband = hFreq->highSubband; 5322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noSubbands = highSubband - lowSubband; 5332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noNoiseBands = hFreq->nNfb; 5352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int no_cols = hHeaderData->numberTimeSlots * hHeaderData->timeStep; 5362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR first_start = borders[0] * hHeaderData->timeStep; 5372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR sineMapped[MAX_FREQ_COEFFS]; 5392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR ov_adj_e = SCALE2EXP(sbrScaleFactor->ov_hb_scale); 5402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR adj_e = 0; 5412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR output_e; 5422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR final_e = 0; 5432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR maxGainLimit_e = (frameErrorFlag) ? MAX_GAIN_CONCEAL_EXP : MAX_GAIN_EXP; 5452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int useAliasReduction[64]; 5472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR smooth_length = 0; 5482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL * pIenv = hFrameData->iEnvelope; 5502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 5522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Extract sine flags for all QMF bands 5532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 5542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project mapSineFlags(hFreq->freqBandTable[1], 5552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFreq->nSfb[1], 5562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFrameData->addHarmonics, 5572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->harmFlagsPrev, 5582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFrameData->frameInfo.tranEnv, 5592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineMapped); 5602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 5632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Scan for maximum in bufferd noise levels. 5642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This is needed in case that we had strong noise in the previous frame 5652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project which is smoothed into the current frame. 5662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The resulting exponent is used as start value for the maximum search 5672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project in reference energies 5682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 5692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 5702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project adj_e = h_sbr_cal_env->filtBufferNoise_e - getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands); 5712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 5732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Scan for maximum reference energy to be able 5742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project to select appropriate values for adj_e and final_e. 5752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 5762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) { 5782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project INT maxSfbNrg_e = -FRACT_BITS+NRG_EXP_OFFSET; /* start value for maximum search */ 5792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Fetch frequency resolution for current envelope: */ 5812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (j=hFreq->nSfb[hFrameData->frameInfo.freqRes[i]]; j!=0; j--) { 5822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxSfbNrg_e = fixMax(maxSfbNrg_e,(INT)((LONG)(*pIenv++) & MASK_E)); 5832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 5842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxSfbNrg_e -= NRG_EXP_OFFSET; 5852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Energy -> magnitude (sqrt halfens exponent) */ 5872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxSfbNrg_e = (maxSfbNrg_e+1) >> 1; /* +1 to go safe (round to next higher int) */ 5882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Some safety margin is needed for 2 reasons: 5902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project - The signal energy is not equally spread over all subband samples in 5912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project a specific sfb of an envelope (Nrg could be too high by a factor of 5922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project envWidth * sfbWidth) 5932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project - Smoothing can smear high gains of the previous envelope into the current 5942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 5952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxSfbNrg_e += 6; 5962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 5972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (borders[i] < hHeaderData->numberTimeSlots) 5982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* This envelope affects timeslots that belong to the output frame */ 5992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project adj_e = (maxSfbNrg_e > adj_e) ? maxSfbNrg_e : adj_e; 6002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (borders[i+1] > hHeaderData->numberTimeSlots) 6022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* This envelope affects timeslots after the output frame */ 6032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project final_e = (maxSfbNrg_e > final_e) ? maxSfbNrg_e : final_e; 6042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 6082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Calculate adjustment factors and apply them for every envelope. 6092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 6102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pIenv = hFrameData->iEnvelope; 6112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) { 6132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k, noNoiseFlag; 6152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR noise_e, input_e = SCALE2EXP(sbrScaleFactor->hb_scale); 6162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project C_ALLOC_SCRATCH_START(pNrgs, ENV_CALC_NRGS, 1); 6172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 6192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Helper variables. 6202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 6212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR start_pos = hHeaderData->timeStep * borders[i]; /* Start-position in time (subband sample) for current envelope. */ 6222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR stop_pos = hHeaderData->timeStep * borders[i+1]; /* Stop-position in time (subband sample) for current envelope. */ 6232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR freq_res = hFrameData->frameInfo.freqRes[i]; /* Frequency resolution for current envelope. */ 6242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Always do fully initialize the temporary energy table. This prevents negative energies and extreme gain factors in 6272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project cases where the number of limiter bands exceeds the number of subbands. The latter can be caused by undetected bit 6282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project errors and is tested by some streams from the certification set. */ 6292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemclear(pNrgs, sizeof(ENV_CALC_NRGS)); 6302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* If the start-pos of the current envelope equals the stop pos of the current 6322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noise envelope, increase the pointer (i.e. choose the next noise-floor).*/ 6332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (borders[i] == hFrameData->frameInfo.bordersNoise[envNoise+1]){ 6342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noiseLevels += noNoiseBands; /* The noise floor data is stored in a row [noiseFloor1 noiseFloor2...].*/ 6352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project envNoise++; 6362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(i==hFrameData->frameInfo.tranEnv || i==h_sbr_cal_env->prevTranEnv) /* attack */ 6392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 6402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noNoiseFlag = 1; 6412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 6422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smooth_length = 0; /* No smoothing on attacks! */ 6432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 6452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noNoiseFlag = 0; 6462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 6472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smooth_length = (1 - hHeaderData->bs_data.smoothingLength) << 2; /* can become either 0 or 4 */ 6482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 6522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Energy estimation in transposed highband. 6532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 6542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (hHeaderData->bs_data.interpolFreq) 6552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project calcNrgPerSubband(analysBufferReal, 6562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (useLP) ? NULL : analysBufferImag, 6572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, highSubband, 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 else 6632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project calcNrgPerSfb(analysBufferReal, 6642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (useLP) ? NULL : analysBufferImag, 6652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFreq->nSfb[freq_res], 6662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFreq->freqBandTable[freq_res], 6672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project start_pos, stop_pos, 6682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project input_e, 6692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgEst, 6702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgEst_e); 6712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 6732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Calculate subband gains 6742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 6752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 6762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR * table = hFreq->freqBandTable[freq_res]; 6772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR * pUiNoise = &hFreq->freqBandTableNoise[1]; /*! Upper limit of the current noise floor band. */ 6782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL * pNoiseLevels = noiseLevels; 6802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmpNoise = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M)); 6822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR tmpNoise_e = (UCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET; 6832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int cc = 0; 6852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project c = 0; 6862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (j = 0; j < hFreq->nSfb[freq_res]; j++) { 6872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL refNrg = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pIenv) & MASK_M)); 6892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR refNrg_e = (SCHAR)((LONG)(*pIenv) & MASK_E) - NRG_EXP_OFFSET; 6902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR sinePresentFlag = 0; 6922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int li = table[j]; 6932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int ui = table[j+1]; 6942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=li; k<ui; k++) { 6962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sinePresentFlag |= (i >= sineMapped[cc]); 6972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project cc++; 6982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 6992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=li; k<ui; k++) { 7012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (k >= *pUiNoise) { 7022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmpNoise = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M)); 7032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmpNoise_e = (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET; 7042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pUiNoise++; 7062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_ASSERT(k >= lowSubband); 7092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (useLP) 7112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project useAliasReduction[k-lowSubband] = !sinePresentFlag; 7122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f); 7142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgSine_e[c] = 0; 7152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project calcSubbandGain(refNrg, refNrg_e, pNrgs, c, 7172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tmpNoise, tmpNoise_e, 7182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sinePresentFlag, i >= sineMapped[c], 7192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noNoiseFlag); 7202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgRef[c] = refNrg; 7222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgRef_e[c] = refNrg_e; 7232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project c++; 7252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pIenv++; 7272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 7312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Noise limiting 7322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 7332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (c = 0; c < hFreq->noLimiterBands; c++) { 7352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sumRef, boostGain, maxGain; 7372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL accu = FL2FXCONST_DBL(0.0f); 7382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR sumRef_e, boostGain_e, maxGain_e, accu_e = 0; 7392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project calcAvgGain(pNrgs, 7412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hFreq->limiterBandTable[c], hFreq->limiterBandTable[c+1], 7422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &sumRef, &sumRef_e, 7432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &maxGain, &maxGain_e); 7442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Multiply maxGain with limiterGain: */ 7462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain = fMult(maxGain, FDK_sbrDecoder_sbr_limGains_m[hHeaderData->bs_data.limiterGains]); 7472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain_e += FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains]; 7482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Scale mantissa of MaxGain into range between 0.5 and 1: */ 7502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (maxGain == FL2FXCONST_DBL(0.0f)) 7512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain_e = -FRACT_BITS; 7522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 7532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR charTemp = CountLeadingBits(maxGain); 7542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain_e -= charTemp; 7552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain <<= (int)charTemp; 7562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (maxGain_e >= maxGainLimit_e) { /* upper limit (e.g. 96 dB) */ 7592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain = FL2FXCONST_DBL(0.5f); 7602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxGain_e = maxGainLimit_e; 7612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Every subband gain is compared to the scaled "average gain" 7652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and limited if necessary: */ 7662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c+1]; k++) { 7672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( (pNrgs->nrgGain_e[k] > maxGain_e) || (pNrgs->nrgGain_e[k] == maxGain_e && pNrgs->nrgGain[k]>maxGain) ) { 7682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL noiseAmp; 7702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR noiseAmp_e; 7712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp(maxGain, maxGain_e, pNrgs->nrgGain[k], pNrgs->nrgGain_e[k], &noiseAmp, &noiseAmp_e); 7732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->noiseLevel[k] = fMult(pNrgs->noiseLevel[k],noiseAmp); 7742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->noiseLevel_e[k] += noiseAmp_e; 7752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain[k] = maxGain; 7762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain_e[k] = maxGain_e; 7772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* -- Boost gain 7812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Calculate and apply boost factor for each limiter band: 7822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1. Check how much energy would be present when using the limited gain 7832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2. Calculate boost factor by comparison with reference energy 7842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 3. Apply boost factor to compensate for the energy loss due to limiting 7852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 7862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; k++) { 7872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 1.a Add energy of adjusted signal (using preliminary gain) */ 7892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp = fMult(pNrgs->nrgGain[k],pNrgs->nrgEst[k]); 7902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR tmp_e = pNrgs->nrgGain_e[k] + pNrgs->nrgEst_e[k]; 7912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp(tmp, tmp_e, accu, accu_e, &accu, &accu_e); 7922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 7932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 1.b Add sine energy (if present) */ 7942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(pNrgs->nrgSine[k] != FL2FXCONST_DBL(0.0f)) { 7952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp(pNrgs->nrgSine[k], pNrgs->nrgSine_e[k], accu, accu_e, &accu, &accu_e); 7962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 7972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 7982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 1.c Add noise energy (if present) */ 7992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(noNoiseFlag == 0) { 8002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp(pNrgs->noiseLevel[k], pNrgs->noiseLevel_e[k], accu, accu_e, &accu, &accu_e); 8012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 2.a Calculate ratio of wanted energy and accumulated energy */ 8062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (accu == (FIXP_DBL)0) { /* If divisor is 0, limit quotient to +4 dB */ 8072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project boostGain = FL2FXCONST_DBL(0.6279716f); 8082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project boostGain_e = 2; 8092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 8102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project INT div_e; 8112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project boostGain = fDivNorm(sumRef, accu, &div_e); 8122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project boostGain_e = sumRef_e - accu_e + div_e; 8132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 2.b Result too high? --> Limit the boost factor to +4 dB */ 8172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if((boostGain_e > 3) || 8182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (boostGain_e == 2 && boostGain > FL2FXCONST_DBL(0.6279716f)) || 8192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (boostGain_e == 3 && boostGain > FL2FXCONST_DBL(0.3139858f)) ) 8202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 8212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project boostGain = FL2FXCONST_DBL(0.6279716f); 8222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project boostGain_e = 2; 8232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 3. Multiply all signal components with the boost factor */ 8252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; k++) { 8262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain[k] = fMultDiv2(pNrgs->nrgGain[k],boostGain); 8272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain_e[k] = pNrgs->nrgGain_e[k] + boostGain_e + 1; 8282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgSine[k] = fMultDiv2(pNrgs->nrgSine[k],boostGain); 8302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgSine_e[k] = pNrgs->nrgSine_e[k] + boostGain_e + 1; 8312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->noiseLevel[k] = fMultDiv2(pNrgs->noiseLevel[k],boostGain); 8332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->noiseLevel_e[k] = pNrgs->noiseLevel_e[k] + boostGain_e + 1; 8342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* End of noise limiting */ 8372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (useLP) 8392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project aliasingReduction(degreeAlias+lowSubband, 8402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs, 8412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project useAliasReduction, 8422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noSubbands); 8432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* For the timeslots within the range for the output frame, 8452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project use the same scale for the noise levels. 8462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Drawback: If the envelope exceeds the frame border, the noise levels 8472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project will have to be rescaled later to fit final_e of 8482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the gain-values. 8492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 8502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noise_e = (start_pos < no_cols) ? adj_e : final_e; 8512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 8532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Convert energies to amplitude levels 8542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 8552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) { 8562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_sqrt_MantExp(&pNrgs->nrgSine[k], &pNrgs->nrgSine_e[k], &noise_e); 8572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_sqrt_MantExp(&pNrgs->nrgGain[k], &pNrgs->nrgGain_e[k], &pNrgs->nrgGain_e[k]); 8582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_sqrt_MantExp(&pNrgs->noiseLevel[k], &pNrgs->noiseLevel_e[k], &noise_e); 8592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 8642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Apply calculated gains and adaptive noise 8652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 8662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* assembleHfSignals() */ 8682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 8692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int scale_change, sc_change; 8702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL smooth_ratio; 8712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int filtBufferNoiseShift=0; 8722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Initialize smoothing buffers with the first valid values */ 8742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (h_sbr_cal_env->startUp) 8752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 8762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) { 8772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise_e = noise_e; 8782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e, noSubbands*sizeof(SCHAR)); 8802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, noSubbands*sizeof(FIXP_DBL)); 8812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain, noSubbands*sizeof(FIXP_DBL)); 8822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->startUp = 0; 8852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 8862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) { 8882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project equalizeFiltBufferExp(h_sbr_cal_env->filtBuffer, /* buffered */ 8902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBuffer_e, /* buffered */ 8912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain, /* current */ 8922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain_e, /* current */ 8932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noSubbands); 8942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 8952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Adapt exponent of buffered noise levels to the current exponent 8962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project so they can easily be smoothed */ 8972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if((h_sbr_cal_env->filtBufferNoise_e - noise_e)>=0) { 8982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int shift = fixMin(DFRACT_BITS-1,(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e)); 8992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) 9002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise[k] <<= shift; 9012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 9032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int shift = fixMin(DFRACT_BITS-1,-(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e)); 9042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) 9052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise[k] >>= shift; 9062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise_e = noise_e; 9092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* find best scaling! */ 9122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change = -(DFRACT_BITS-1); 9132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k=0;k<noSubbands;k++) { 9142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change = fixMax(scale_change,(int)pNrgs->nrgGain_e[k]); 9152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sc_change = (start_pos<no_cols)? adj_e - input_e : final_e - input_e; 9172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ((scale_change-sc_change+1)<0) 9192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change-=(scale_change-sc_change+1); 9202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change = (scale_change-sc_change)+1; 9222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k=0;k<noSubbands;k++) { 9242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int sc = scale_change-pNrgs->nrgGain_e[k] + (sc_change-1); 9252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain[k] >>= sc; 9262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain_e[k] += sc; 9272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) { 9302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k=0;k<noSubbands;k++) { 9312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int sc = scale_change-h_sbr_cal_env->filtBuffer_e[k] + (sc_change-1); 9322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBuffer[k] >>= sc; 9332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (j = start_pos; j < stop_pos; j++) 9372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 9382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* This timeslot is located within the first part of the processing buffer 9392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and will be fed into the QMF-synthesis for the current frame. 9402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project adj_e - input_e 9412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This timeslot will not yet be fed into the QMF so we do not care 9422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project about the adj_e. 9432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sc_change = final_e - input_e 9442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 9452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( (j==no_cols) && (start_pos<no_cols) ) 9462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 9472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int shift = (int) (noise_e - final_e); 9482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 9492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBufferNoiseShift = shift; /* shifting of h_sbr_cal_env->filtBufferNoise[k] will be applied in function adjustTimeSlotHQ() */ 9502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (shift>=0) { 9512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = fixMin(DFRACT_BITS-1,shift); 9522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) { 9532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgSine[k] <<= shift; 9542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->noiseLevel[k] <<= shift; 9552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 9562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 9572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise[k] <<= shift; 9582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 9592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 9622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = fixMin(DFRACT_BITS-1,-shift); 9632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) { 9642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgSine[k] >>= shift; 9652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->noiseLevel[k] >>= shift; 9662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 9672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 9682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise[k] >>= shift; 9692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 9702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* update noise scaling */ 9742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noise_e = final_e; 9752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) 9762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBufferNoise_e = noise_e; /* scaling value unused! */ 9772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* update gain buffer*/ 9792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sc_change -= (final_e - input_e); 9802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (sc_change<0) { 9822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k=0;k<noSubbands;k++) { 9832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain[k] >>= -sc_change; 9842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs->nrgGain_e[k] += -sc_change; 9852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) { 9872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(k=0;k<noSubbands;k++) { 9882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->filtBuffer[k] >>= -sc_change; 9892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 9922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change+=sc_change; 9932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 9942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } // if 9962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) { 9982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 9992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Prevent the smoothing filter from running on constant levels */ 10002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (j-start_pos < smooth_length) 10012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j-start_pos]; 10022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 10032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smooth_ratio = FL2FXCONST_SGL(0.0f); 10042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project adjustTimeSlotHQ(&analysBufferReal[j][lowSubband], 10062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &analysBufferImag[j][lowSubband], 10072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env, 10082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs, 10092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, 10102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noSubbands, 10112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change, 10122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smooth_ratio, 10132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noNoiseFlag, 10142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBufferNoiseShift); 10152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 10172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 1018203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi if (flags & SBRDEC_ELD_GRID) { 1019203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband], 10202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNrgs, 10212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &h_sbr_cal_env->harmIndex, 10222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, 10232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noSubbands, 10242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scale_change, 10252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noNoiseFlag, 10262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &h_sbr_cal_env->phaseIndex, 1027203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale); 1028203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi } else 1029203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi { 1030203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi adjustTimeSlotLC(&analysBufferReal[j][lowSubband], 1031203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi pNrgs, 1032203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi &h_sbr_cal_env->harmIndex, 1033203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi lowSubband, 1034203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi noSubbands, 1035203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi scale_change, 1036203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi noNoiseFlag, 1037203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi &h_sbr_cal_env->phaseIndex); 1038203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi } 10392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } // for 10412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!useLP) { 10432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Update time-smoothing-buffers for gains and noise levels 10442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The gains and the noise values of the current envelope are copied into the buffer. 10452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This has to be done at the end of each envelope as the values are required for 10462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project a smooth transition to the next envelope. */ 10472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain, noSubbands*sizeof(FIXP_DBL)); 10482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e, noSubbands*sizeof(SCHAR)); 10492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, noSubbands*sizeof(FIXP_DBL)); 10502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project C_ALLOC_SCRATCH_END(pNrgs, ENV_CALC_NRGS, 1); 10542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 10552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Rescale output samples */ 10572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 10582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL maxVal; 10592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int ov_reserve, reserve; 10602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Determine headroom in old adjusted samples */ 10622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal = maxSubbandSample( analysBufferReal, 10632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (useLP) ? NULL : analysBufferImag, 10642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, 10652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project highSubband, 10662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 0, 10672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project first_start); 10682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ov_reserve = fNorm(maxVal); 10702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Determine headroom in new adjusted samples */ 10722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal = maxSubbandSample( analysBufferReal, 10732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (useLP) ? NULL : analysBufferImag, 10742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, 10752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project highSubband, 10762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project first_start, 10772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project no_cols); 10782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project reserve = fNorm(maxVal); 10802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Determine common output exponent */ 10822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (ov_adj_e - ov_reserve > adj_e - reserve ) /* set output_e to the maximum */ 10832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project output_e = ov_adj_e - ov_reserve; 10842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 10852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project output_e = adj_e - reserve; 10862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Rescale old samples */ 10882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project rescaleSubbandSamples( analysBufferReal, 10892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (useLP) ? NULL : analysBufferImag, 10902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, highSubband, 10912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 0, first_start, 10922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ov_adj_e - output_e); 10932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 10942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Rescale new samples */ 10952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project rescaleSubbandSamples( analysBufferReal, 10962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (useLP) ? NULL : analysBufferImag, 10972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project lowSubband, highSubband, 10982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project first_start, no_cols, 10992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project adj_e - output_e); 11002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Update hb_scale */ 11032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sbrScaleFactor->hb_scale = EXP2SCALE(output_e); 11042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Save the current final exponent for the next frame: */ 11062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sbrScaleFactor->ov_hb_scale = EXP2SCALE(final_e); 11072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* We need to remeber to the next frame that the transient 11102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project will occur in the first envelope (if tranEnv == nEnvelopes). */ 11112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(hFrameData->frameInfo.tranEnv == hFrameData->frameInfo.nEnvelopes) 11122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->prevTranEnv = 0; 11132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 11142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project h_sbr_cal_env->prevTranEnv = -1; 11152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 11172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 11202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Create envelope instance 11212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Must be called once for each channel before calculateSbrEnvelope() can be used. 11232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \return errorCode, 0 if successful 11252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 11262228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectSBR_ERROR 11272228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectcreateSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hs, /*!< pointer to envelope instance */ 11282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_SBR_HEADER_DATA hHeaderData, /*!< static SBR control data, initialized with defaults */ 11292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const int chan, /*!< Channel for which to assign buffers */ 11302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const UINT flags) 11312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 11322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SBR_ERROR err = SBRDEC_OK; 11332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int i; 11342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Clear previous missing harmonics flags */ 11362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (i=0; i<(MAX_FREQ_COEFFS+15)>>4; i++) { 11372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hs->harmFlagsPrev[i] = 0; 11382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hs->harmIndex = 0; 11402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 11422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Setup pointers for time smoothing. 11432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The buffer itself will be initialized later triggered by the startUp-flag. 11442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 11452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hs->prevTranEnv = -1; 11462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* initialization */ 11492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project resetSbrEnvelopeCalc(hs); 11502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (chan==0) { /* do this only once */ 11522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project err = resetFreqBandTables(hHeaderData, flags); 11532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 11542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return err; 11562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 11572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 11592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Create envelope instance 11602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Must be called once for each channel before calculateSbrEnvelope() can be used. 11622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \return errorCode, 0 if successful 11642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 11652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint 11662228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectdeleteSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hs) 11672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 11682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return 0; 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 Reset envelope instance 11742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function must be called for each channel on a change of configuration. 11762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Note that resetFreqBandTables should also be called in this case. 11772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \return errorCode, 0 if successful 11792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 11802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid 11812228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectresetSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to envelope instance */ 11822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 11832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hCalEnv->phaseIndex = 0; 11842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Noise exponent needs to be reset because the output exponent for the next frame depends on it */ 11862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hCalEnv->filtBufferNoise_e = 0; 11872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hCalEnv->startUp = 1; 11892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 11902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 11932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Equalize exponents of the buffered gain values and the new ones 11942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 11952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project After equalization of exponents, the FIR-filter addition for smoothing 11962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project can be performed. 11972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function is called once for each envelope before adjusting. 11982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 1199203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */ 12002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *filtBuffer_e, /*!< exponents of bufferd gains */ 12012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *nrgGain, /*!< gains for current envelope */ 12022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *nrgGain_e, /*!< exponents of gains for current envelope */ 12032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int subbands) /*!< Number of QMF subbands */ 12042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 12052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int band; 12062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int diff; 12072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (band=0; band<subbands; band++){ 12092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project diff = (int) (nrgGain_e[band] - filtBuffer_e[band]); 12102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (diff>0) { 12112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBuffer[band] >>= diff; /* Compensate for the scale change by shifting the mantissa. */ 12122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */ 12132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else if (diff<0) { 12152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The buffered gains seem to be larger, but maybe there 12162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project are some unused bits left in the mantissa */ 12172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int reserve = CntLeadingZeros(fixp_abs(filtBuffer[band]))-1; 12192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ((-diff) <= reserve) { 12212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* There is enough space in the buffered mantissa so 12222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project that we can take the new exponent as common. 12232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 12242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBuffer[band] <<= (-diff); 12252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBuffer_e[band] += diff; /* becomes equal to *ptrNewExp */ 12262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 12282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBuffer[band] <<= reserve; /* Shift the mantissa as far as possible: */ 12292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */ 12302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* For the remaining difference, change the new gain value */ 12322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project diff = fixMin(-(reserve + diff),DFRACT_BITS-1); 12332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgGain[band] >>= diff; 12342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgGain_e[band] += diff; 12352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 12392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 12412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Shift left the mantissas of all subband samples 12422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project in the giventime and frequency range by the specified number of bits. 12432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function is used to rescale the audio data in the overlap buffer 12452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project which has already been envelope adjusted with the last frame. 12462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 12472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid rescaleSubbandSamples(FIXP_DBL ** re, /*!< Real part of input and output subband samples */ 12482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL ** im, /*!< Imaginary part of input and output subband samples */ 12492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, /*!< Begin of frequency range to process */ 12502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int highSubband, /*!< End of frequency range to process */ 12512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int start_pos, /*!< Begin of time rage (QMF-timeslot) */ 12522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int next_pos, /*!< End of time rage (QMF-timeslot) */ 12532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int shift) /*!< number of bits to shift */ 12542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 12552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int width = highSubband-lowSubband; 12562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( (width > 0) && (shift!=0) ) { 12582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (im!=NULL) { 12592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (int l=start_pos; l<next_pos; l++) { 12602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scaleValues(&re[l][lowSubband], width, shift); 12612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scaleValues(&im[l][lowSubband], width, shift); 12622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else 12642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 12652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (int l=start_pos; l<next_pos; l++) { 12662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project scaleValues(&re[l][lowSubband], width, shift); 12672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 12702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 12712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 12742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Determine headroom for shifting 12752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Determine by how much the spectrum can be shifted left 12772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for better accuracy in later processing. 12782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \return Number of free bits in the biggest spectral value 12802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 12812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12822228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output subband samples */ 12832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL ** im, /*!< Real part of input and output subband samples */ 12842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, /*!< Begin of frequency range to process */ 12852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int highSubband, /*!< Number of QMF bands to process */ 12862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int start_pos, /*!< Begin of time rage (QMF-timeslot) */ 12872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int next_pos /*!< End of time rage (QMF-timeslot) */ 12882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ) 12892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 12902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL maxVal = FL2FX_DBL(0.0f); 12912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project unsigned int width = highSubband - lowSubband; 12922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_ASSERT(width <= (64)); 12942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 12952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( width > 0 ) { 12962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (im!=NULL) 12972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 12982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (int l=start_pos; l<next_pos; l++) 12992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 13002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef FUNCTION_FDK_get_maxval 13012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal = FDK_get_maxval(maxVal, &re[l][lowSubband], &im[l][lowSubband], width); 13022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#else 13032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k=width; 13042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *reTmp = &re[l][lowSubband]; 13052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *imTmp = &im[l][lowSubband]; 13062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project do{ 13072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp1 = *(reTmp++); 13082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp2 = *(imTmp++); 13092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal |= (FIXP_DBL)((LONG)(tmp1)^((LONG)tmp1>>(DFRACT_BITS-1))); 13102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal |= (FIXP_DBL)((LONG)(tmp2)^((LONG)tmp2>>(DFRACT_BITS-1))); 13112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } while(--k!=0); 13122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif 13132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else 13152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 13162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (int l=start_pos; l<next_pos; l++) { 13172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k=width; 13182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *reTmp = &re[l][lowSubband]; 13192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project do{ 13202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp = *(reTmp++); 13212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal |= (FIXP_DBL)((LONG)(tmp)^((LONG)tmp>>(DFRACT_BITS-1))); 13222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project }while(--k!=0); 13232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return(maxVal); 13282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 13292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define SHIFT_BEFORE_SQUARE (3) /* (7/2) */ 13312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!< 13322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project If the accumulator does not provide enough overflow bits or 13332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project does not provide a high dynamic range, the below energy calculation 13342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project requires an additional shift operation for each sample. 13352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project On the other hand, doing the shift allows using a single-precision 13362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project multiplication for the square (at least 16bit x 16bit). 13372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project For even values of OVRFLW_BITS (0, 2, 4, 6), saturated arithmetic 13382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project is required for the energy accumulation. 13392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Theoretically, the sample-squares can sum up to a value of 76, 13402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project requiring 7 overflow bits. However since such situations are *very* 13412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project rare, accu can be limited to 64. 13422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project In case native saturated arithmetic is not available, overflows 13432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project can be prevented by replacing the above #define by 13442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project #define SHIFT_BEFORE_SQUARE ((8 - OVRFLW_BITS) / 2) 13452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project which will result in slightly reduced accuracy. 13462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 13472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 13492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Estimates the mean energy of each filter-bank channel for the 13502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project duration of the current envelope 13512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function is used when interpolFreq is true. 13532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 1354203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ 13552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */ 13562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, /*!< Begin of the SBR frequency range */ 13572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int highSubband, /*!< High end of the SBR frequency range */ 13582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int start_pos, /*!< First QMF-slot of current envelope */ 13592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int next_pos, /*!< Last QMF-slot of current envelope + 1 */ 13602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR frameExp, /*!< Common exponent for all input samples */ 13612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */ 13622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *nrgEst_e ) /*!< Exponent of resulting Energy */ 13632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 13642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL invWidth; 13652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR preShift; 13662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR shift; 13672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sum; 13682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k,l; 13692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Divide by width of envelope later: */ 13712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos)); 13722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The common exponent needs to be doubled because all mantissas are squared: */ 13732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project frameExp = frameExp << 1; 13742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=lowSubband; k<highSubband; k++) { 13762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL bufferReal[(((1024)/(32))+(6))]; 13772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL bufferImag[(((1024)/(32))+(6))]; 13782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL maxVal = FL2FX_DBL(0.0f); 13792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (analysBufferImag!=NULL) 13812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 13822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos;l<next_pos;l++) 13832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 13842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bufferImag[l] = analysBufferImag[l][k]; 13852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal |= (FIXP_DBL)((LONG)(bufferImag[l])^((LONG)bufferImag[l]>>(DFRACT_BITS-1))); 13862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bufferReal[l] = analysBufferReal[l][k]; 13872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal |= (FIXP_DBL)((LONG)(bufferReal[l])^((LONG)bufferReal[l]>>(DFRACT_BITS-1))); 13882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 13912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 13922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos;l<next_pos;l++) 13932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 13942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project bufferReal[l] = analysBufferReal[l][k]; 13952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project maxVal |= (FIXP_DBL)((LONG)(bufferReal[l])^((LONG)bufferReal[l]>>(DFRACT_BITS-1))); 13962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 13982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 13992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (maxVal!=FL2FXCONST_DBL(0.f)) { 14002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* If the accu does not provide enough overflow bits, we cannot 14032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift the samples up to the limit. 14042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Instead, keep up to 3 free bits in each sample, i.e. up to 14052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6 bits after calculation of square. 14062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Please note the comment on saturated arithmetic above! 14072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 14082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL accu = FL2FXCONST_DBL(0.0f); 14092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project preShift = CntLeadingZeros(maxVal)-1; 14102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project preShift -= SHIFT_BEFORE_SQUARE; 14112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (preShift>=0) { 14132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (analysBufferImag!=NULL) { 14142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 14152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp1 = bufferReal[l] << (int)preShift; 14162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp2 = bufferImag[l] << (int)preShift; 14172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu = fPow2AddDiv2(accu, temp1); 14182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu = fPow2AddDiv2(accu, temp2); 14192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else 14212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 14222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 14232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp = bufferReal[l] << (int)preShift; 14242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu = fPow2AddDiv2(accu, temp); 14252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { /* if negative shift value */ 14292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int negpreShift = -preShift; 14302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (analysBufferImag!=NULL) { 14312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 14322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp1 = bufferReal[l] >> (int)negpreShift; 14332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp2 = bufferImag[l] >> (int)negpreShift; 14342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu = fPow2AddDiv2(accu, temp1); 14352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu = fPow2AddDiv2(accu, temp2); 14362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else 14382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 14392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 14402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp = bufferReal[l] >> (int)negpreShift; 14412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu = fPow2AddDiv2(accu, temp); 14422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project accu <<= 1; 14462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Convert double precision to Mantissa/Exponent: */ 14482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = fNorm(accu); 14492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum = accu << (int)shift; 14502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Divide by width of envelope and apply frame scale: */ 14522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst++ = fMult(sum, invWidth); 14532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift += 2 * preShift; 14542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (analysBufferImag!=NULL) 14552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst_e++ = frameExp - shift; 14562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 14572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst_e++ = frameExp - shift + 1; /* +1 due to missing imag. part */ 14582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } /* maxVal!=0 */ 14592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 14602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Prevent a zero-mantissa-number from being misinterpreted 14622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project due to its exponent. */ 14632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst++ = FL2FXCONST_DBL(0.0f); 14642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst_e++ = 0; 14652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 14672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 14682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 14702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Estimates the mean energy of each Scale factor band for the 14712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project duration of the current envelope. 14722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This function is used when interpolFreq is false. 14742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 1475203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ 14762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */ 14772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int nSfb, /*!< Number of scale factor bands */ 14782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *freqBandTable, /*!< First Subband for each Sfb */ 14792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int start_pos, /*!< First QMF-slot of current envelope */ 14802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int next_pos, /*!< Last QMF-slot of current envelope + 1 */ 14812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR input_e, /*!< Common exponent for all input samples */ 14822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */ 14832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *nrgEst_e ) /*!< Exponent of resulting Energy */ 14842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 14852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL invWidth; 14862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL temp; 14872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR preShift; 14882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR shift, sum_e; 14892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sum; 14902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int j,k,l,li,ui; 14922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sumAll, sumLine; /* Single precision would be sufficient, 14932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project but overflow bits are required for accumulation */ 14942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 14952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Divide by width of envelope later: */ 14962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos)); 14972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The common exponent needs to be doubled because all mantissas are squared: */ 14982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project input_e = input_e << 1; 14992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for(j=0; j<nSfb; j++) { 15012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project li = freqBandTable[j]; 15022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ui = freqBandTable[j+1]; 15032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL maxVal = maxSubbandSample( analysBufferReal, 15052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project analysBufferImag, 15062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project li, 15072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ui, 15082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project start_pos, 15092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project next_pos ); 15102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (maxVal!=FL2FXCONST_DBL(0.f)) { 15122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project preShift = CntLeadingZeros(maxVal)-1; 15142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* If the accu does not provide enough overflow bits, we cannot 15162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift the samples up to the limit. 15172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Instead, keep up to 3 free bits in each sample, i.e. up to 15182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 6 bits after calculation of square. 15192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Please note the comment on saturated arithmetic above! 15202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 15212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project preShift -= SHIFT_BEFORE_SQUARE; 15222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumAll = FL2FXCONST_DBL(0.0f); 15242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=li; k<ui; k++) { 15272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine = FL2FXCONST_DBL(0.0f); 15292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (analysBufferImag!=NULL) { 15312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (preShift>=0) { 15322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 15332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = analysBufferReal[l][k] << (int)preShift; 15342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine += fPow2Div2(temp); 15352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = analysBufferImag[l][k] << (int)preShift; 15362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine += fPow2Div2(temp); 15372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 15402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 15412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = analysBufferReal[l][k] >> -(int)preShift; 15422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine += fPow2Div2(temp); 15432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = analysBufferImag[l][k] >> -(int)preShift; 15442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine += fPow2Div2(temp); 15452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else 15482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 15492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (preShift>=0) { 15502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 15512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = analysBufferReal[l][k] << (int)preShift; 15522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine += fPow2Div2(temp); 15532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 15552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (l=start_pos; l<next_pos; l++) { 15562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project temp = analysBufferReal[l][k] >> -(int)preShift; 15572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine += fPow2Div2(temp); 15582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The number of QMF-channels per SBR bands may be up to 15. 15632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Shift right to avoid overflows in sum over all channels. */ 15642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumLine = sumLine >> (4-1); 15652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumAll += sumLine; 15662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Convert double precision to Mantissa/Exponent: */ 15692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = fNorm(sumAll); 15702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum = sumAll << (int)shift; 15712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Divide by width of envelope: */ 15732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum = fMult(sum,invWidth); 15742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Divide by width of Sfb: */ 15762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum = fMult(sum, FX_DBL2FX_SGL(GetInvInt(ui-li))); 15772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Set all Subband energies in the Sfb to the average energy: */ 15792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (analysBufferImag!=NULL) 15802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum_e = input_e + 4 - shift; /* -4 to compensate right-shift */ 15812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 15822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum_e = input_e + 4 + 1 - shift; /* -4 to compensate right-shift; +1 due to missing imag. part */ 15832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum_e -= 2 * preShift; 15852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } /* maxVal!=0 */ 15862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 15872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Prevent a zero-mantissa-number from being misinterpreted 15892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project due to its exponent. */ 15902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum = FL2FXCONST_DBL(0.0f); 15912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sum_e = 0; 15922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 15942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=li; k<ui; k++) 15952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 15962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst++ = sum; 15972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *nrgEst_e++ = sum_e; 15982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 15992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 16012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 16042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Calculate gain, noise, and additional sine level for one subband. 16052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The resulting energy gain is given by mantissa and exponent. 16072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 1608203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */ 16092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */ 16102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ENV_CALC_NRGS* nrgs, 16112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int i, 16122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmpNoise, /*!< Relative noise level */ 16132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR tmpNoise_e, /*!< Relative noise level (exponent) */ 16142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR sinePresentFlag, /*!< Indicates if sine is present on band */ 16152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR sineMapped, /*!< Indicates if sine must be added */ 16162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noNoiseFlag) /*!< Flag to suppress noise addition */ 16172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 16182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL nrgEst = nrgs->nrgEst[i]; /*!< Energy in transposed signal */ 16192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR nrgEst_e = nrgs->nrgEst_e[i]; /*!< Energy in transposed signal (exponent) */ 16202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *ptrNrgGain = &nrgs->nrgGain[i]; /*!< Resulting energy gain */ 16212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *ptrNrgGain_e = &nrgs->nrgGain_e[i]; /*!< Resulting energy gain (exponent) */ 16222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *ptrNoiseLevel = &nrgs->noiseLevel[i]; /*!< Resulting absolute noise energy */ 16232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *ptrNoiseLevel_e = &nrgs->noiseLevel_e[i]; /*!< Resulting absolute noise energy (exponent) */ 16242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *ptrNrgSine = &nrgs->nrgSine[i]; /*!< Additional sine energy */ 16252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *ptrNrgSine_e = &nrgs->nrgSine_e[i]; /*!< Additional sine energy (exponent) */ 16262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL a, b, c; 16282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR a_e, b_e, c_e; 16292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 16312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This addition of 1 prevents divisions by zero in the reference code. 16322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project For very small energies in nrgEst, it prevents the gains from becoming 16332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project very high which could cause some trouble due to the smoothing. 16342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 16352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b_e = (int)(nrgEst_e - 1); 16362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (b_e>=0) { 16372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgEst = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e+1,DFRACT_BITS-1)) + (nrgEst >> 1); 16382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgEst_e += 1; /* shift by 1 bit to avoid overflow */ 16392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 16412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgEst = (nrgEst >> (INT)(fixMin(-b_e+1,DFRACT_BITS-1))) + (FL2FXCONST_DBL(0.5f) >> 1); 16422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgEst_e = 2; /* shift by 1 bit to avoid overflow */ 16432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* A = NrgRef * TmpNoise */ 16462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project a = fMult(nrgRef,tmpNoise); 16472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project a_e = nrgRef_e + tmpNoise_e; 16482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* B = 1 + TmpNoise */ 16502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b_e = (int)(tmpNoise_e - 1); 16512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (b_e>=0) { 16522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e+1,DFRACT_BITS-1)) + (tmpNoise >> 1); 16532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b_e = tmpNoise_e + 1; /* shift by 1 bit to avoid overflow */ 16542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 16552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b = (tmpNoise >> (INT)(fixMin(-b_e+1,DFRACT_BITS-1))) + (FL2FXCONST_DBL(0.5f) >> 1); 16562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b_e = 2; /* shift by 1 bit to avoid overflow */ 16572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */ 16602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp( a, a_e, 16612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b, b_e, 16622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ptrNoiseLevel, ptrNoiseLevel_e); 16632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (sinePresentFlag) { 16652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* C = (1 + TmpNoise) * NrgEst */ 16672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project c = fMult(b,nrgEst); 16682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project c_e = b_e + nrgEst_e; 16692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */ 16712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp( a, a_e, 16722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project c, c_e, 16732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ptrNrgGain, ptrNrgGain_e); 16742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (sineMapped) { 16762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* sineLevel = nrgRef/ (1 + TmpNoise) */ 16782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp( nrgRef, nrgRef_e, 16792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b, b_e, 16802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ptrNrgSine, ptrNrgSine_e); 16812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 16842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (noNoiseFlag) { 16852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* B = NrgEst */ 16862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b = nrgEst; 16872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b_e = nrgEst_e; 16882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 16902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* B = NrgEst * (1 + TmpNoise) */ 16912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b = fMult(b,nrgEst); 16922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b_e = b_e + nrgEst_e; 16932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 16942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 16962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* gain = nrgRef / B */ 16972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp( nrgRef, nrgRef_e, 16982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project b, b_e, 16992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ptrNrgGain, ptrNrgGain_e); 17002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 17012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 17022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 17052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Calculate "average gain" for the specified subband range. 17062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project This is rather a gain of the average magnitude than the average 17082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project of gains! 17092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The result is used as a relative limit for all gains within the 17102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project current "limiter band" (a certain frequency range). 17112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 1712203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic void calcAvgGain(ENV_CALC_NRGS* nrgs, 17132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, /*!< Begin of the limiter band */ 17142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int highSubband, /*!< High end of the limiter band */ 17152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *ptrSumRef, 17162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *ptrSumRef_e, 17172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *ptrAvgGain, /*!< Resulting overall gain (mantissa) */ 17182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *ptrAvgGain_e) /*!< Resulting overall gain (exponent) */ 17192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 17202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *nrgRef = nrgs->nrgRef; /*!< Reference Energy according to envelope data */ 17212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *nrgRef_e = nrgs->nrgRef_e; /*!< Reference Energy according to envelope data (exponent) */ 17222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< Energy in transposed signal */ 17232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR *nrgEst_e = nrgs->nrgEst_e; /*!< Energy in transposed signal (exponent) */ 17242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sumRef = 1; 17262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sumEst = 1; 17272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR sumRef_e = -FRACT_BITS; 17282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project SCHAR sumEst_e = -FRACT_BITS; 17292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k; 17302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=lowSubband; k<highSubband; k++){ 17322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add nrgRef[k] to sumRef: */ 17332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp( sumRef, sumRef_e, 17342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgRef[k], nrgRef_e[k], 17352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &sumRef, &sumRef_e ); 17362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add nrgEst[k] to sumEst: */ 17382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_add_MantExp( sumEst, sumEst_e, 17392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nrgEst[k], nrgEst_e[k], 17402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project &sumEst, &sumEst_e ); 17412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 17422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FDK_divide_MantExp(sumRef, sumRef_e, 17442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sumEst, sumEst_e, 17452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ptrAvgGain, ptrAvgGain_e); 17462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 17472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrSumRef = sumRef; 17482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrSumRef_e = sumRef_e; 17492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 17502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1751203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic void adjustTimeSlot_EldGrid( 1752203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */ 1753203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi ENV_CALC_NRGS* nrgs, 1754203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi UCHAR *ptrHarmIndex, /*!< Harmonic index */ 1755203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ 1756203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int noSubbands, /*!< Number of QMF subbands */ 1757203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int scale_change, /*!< Number of bits to shift adjusted samples */ 1758203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int noNoiseFlag, /*!< Flag to suppress noise addition */ 1759203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int *ptrPhaseIndex, /*!< Start index to random number array */ 1760203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int scale_diff_low) /*!< */ 1761203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi{ 1762203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int k; 1763203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi FIXP_DBL signalReal, sbNoise; 1764203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int tone_count = 0; 1765203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1766203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */ 1767203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */ 1768203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */ 1769203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1770203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int phaseIndex = *ptrPhaseIndex; 1771203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi UCHAR harmIndex = *ptrHarmIndex; 1772203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1773203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi static const INT harmonicPhase [2][4] = { 1774203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi { 1, 0, -1, 0}, 1775203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi { 0, 1, 0, -1} 1776203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi }; 1777203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1778203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi static const FIXP_DBL harmonicPhaseX [2][4] = { 1779203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi { FL2FXCONST_DBL(2.0*1.245183154539139e-001), FL2FXCONST_DBL(2.0*-1.123767859325028e-001), FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0* 1.123767859325028e-001) }, 1780203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi { FL2FXCONST_DBL(2.0*1.245183154539139e-001), FL2FXCONST_DBL(2.0* 1.123767859325028e-001), FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0*-1.123767859325028e-001) } 1781203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi }; 1782203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1783203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi for (k=0; k < noSubbands; k++) { 1784203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1785203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1); 1786203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1787203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi if( (pSineLevel[0] != FL2FXCONST_DBL(0.0f)) || (noNoiseFlag == 1) ){ 1788203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi sbNoise = FL2FXCONST_DBL(0.0f); 1789203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi } else { 1790203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi sbNoise = pNoiseLevel[0]; 1791203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi } 1792203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1793203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi signalReal = fMultDiv2(*ptrReal,*pGain) << ((int)scale_change); 1794203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1795203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise)<<4); 1796203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1797203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi signalReal += pSineLevel[0] * harmonicPhase[0][harmIndex]; 1798203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1799203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi *ptrReal = signalReal; 1800203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1801203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi if (k == 0) { 1802203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi *(ptrReal-1) += scaleValue(fMultDiv2(harmonicPhaseX[lowSubband&1][harmIndex], pSineLevel[0]), -scale_diff_low) ; 1803203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi if (k < noSubbands - 1) { 1804203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi *(ptrReal) += fMultDiv2(pSineLevel[1], harmonicPhaseX[(lowSubband+1)&1][harmIndex]); 1805203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi } 1806203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi } 1807203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi if (k > 0 && k < noSubbands - 1 && tone_count < 16) { 1808203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi *(ptrReal) += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1] [harmIndex]); 1809203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi *(ptrReal) += fMultDiv2(pSineLevel[+ 1], harmonicPhaseX [(lowSubband+k+1)&1][harmIndex]); 1810203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi } 1811203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi if (k == noSubbands - 1 && tone_count < 16) { 1812203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi if (k > 0) { 1813203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi *(ptrReal) += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1][harmIndex]); 1814203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi } 1815203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi if (k + lowSubband + 1< 63) { 1816203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi *(ptrReal+1) += fMultDiv2(pSineLevel[0], harmonicPhaseX[(lowSubband+k+1)&1][harmIndex]); 1817203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi } 1818203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi } 1819203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1820203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi if(pSineLevel[0] != FL2FXCONST_DBL(0.0f)){ 1821203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi tone_count++; 1822203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi } 1823203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi ptrReal++; 1824203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi pNoiseLevel++; 1825203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi pGain++; 1826203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi pSineLevel++; 1827203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi } 1828203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 1829203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi *ptrHarmIndex = (harmIndex + 1) & 3; 1830203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1); 1831203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi} 18322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 18342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Amplify one timeslot of the signal with the calculated gains 18352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project and add the noisefloor. 18362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 18372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1838203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */ 18392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ENV_CALC_NRGS* nrgs, 18402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *ptrHarmIndex, /*!< Harmonic index */ 18412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ 18422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noSubbands, /*!< Number of QMF subbands */ 18432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int scale_change, /*!< Number of bits to shift adjusted samples */ 18442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noNoiseFlag, /*!< Flag to suppress noise addition */ 1845203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi int *ptrPhaseIndex) /*!< Start index to random number array */ 18462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 18472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */ 18482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */ 18492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */ 18502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k; 18522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int index = *ptrPhaseIndex; 18532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR harmIndex = *ptrHarmIndex; 18542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR freqInvFlag = (lowSubband & 1); 18552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev; 18562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int tone_count = 0; 18572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int sineSign = 1; 18582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project #define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f*0.00815f)) 18602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project #define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f*0.16773f)) 18612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 18632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project First pass for k=0 pulled out of the loop: 18642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 18652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index = (index + 1) & (SBR_NF_NO_RANDOM_VAL - 1); 18672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 18692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The next multiplication constitutes the actual envelope adjustment 18702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project of the signal and should be carried out with full accuracy 18712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (supplying #FRACT_BITS valid bits). 18722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 18732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal = fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change); 18742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineLevel = *pSineLevel++; 18752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f); 18762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (sineLevel!=FL2FXCONST_DBL(0.0f)) tone_count++; 18782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else if (!noNoiseFlag) 18792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add noisefloor to the amplified signal */ 18802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4); 18812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 18832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!(harmIndex&0x1)) { 18842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 0,2 */ 18852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += (harmIndex&0x2) ? -sineLevel : sineLevel; 18862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 18872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 18882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 18892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 1,3 in combination with freqInvFlag */ 18902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int shift = (int) (scale_change+1); 18912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = (shift>=0) ? fixMin(DFRACT_BITS-1,shift) : fixMax(-(DFRACT_BITS-1),shift); 18922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp1 = (shift>=0) ? ( fMultDiv2(C1, sineLevel) >> shift ) 18942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project : ( fMultDiv2(C1, sineLevel) << (-shift) ); 18952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL tmp2 = fMultDiv2(C1, sineLevelNext); 18962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 18982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* save switch and compare operations and reduce to XOR statement */ 18992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( ((harmIndex>>1)&0x1)^freqInvFlag) { 19002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *(ptrReal-1) += tmp1; 19012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal -= tmp2; 19022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 19032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *(ptrReal-1) -= tmp1; 19042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += tmp2; 19052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 19072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project freqInvFlag = !freqInvFlag; 19082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNoiseLevel++; 19122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ( noSubbands > 2 ) { 19142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!(harmIndex&0x1)) { 19152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 0,2 */ 19162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(!harmIndex) 19172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 19182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineSign = 0; 19192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=noSubbands-2; k!=0; k--) { 19222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sinelevel = *pSineLevel++; 19232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index++; 19242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (((signalReal = (sineSign ? -sinelevel : sinelevel)) == FL2FXCONST_DBL(0.0f)) && !noNoiseFlag) 19252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 19262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add noisefloor to the amplified signal */ 19272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index &= (SBR_NF_NO_RANDOM_VAL - 1); 19282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4); 19292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The next multiplication constitutes the actual envelope adjustment of the signal. */ 19322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change); 19332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNoiseLevel++; 19352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 19362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } /* for ... */ 19372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 19392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 1,3 in combination with freqInvFlag */ 19402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (harmIndex==1) freqInvFlag = !freqInvFlag; 19412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=noSubbands-2; k!=0; k--) { 19432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index++; 19442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The next multiplication constitutes the actual envelope adjustment of the signal. */ 19452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal = fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change); 19462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (*pSineLevel++!=FL2FXCONST_DBL(0.0f)) tone_count++; 19482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else if (!noNoiseFlag) { 19492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add noisefloor to the amplified signal */ 19502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index &= (SBR_NF_NO_RANDOM_VAL - 1); 19512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4); 19522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project pNoiseLevel++; 19552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (tone_count <= 16) { 19572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL addSine = fMultDiv2((pSineLevel[-2] - pSineLevel[0]), C1); 19582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += (freqInvFlag) ? (-addSine) : (addSine); 19592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 19622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project freqInvFlag = !freqInvFlag; 19632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } /* for ... */ 19642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (noSubbands > -1) { 19682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index++; 19692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* The next multiplication constitutes the actual envelope adjustment of the signal. */ 19702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal = fMultDiv2(*ptrReal,*pGain) << ((int)scale_change); 19712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineLevelPrev = fMultDiv2(pSineLevel[-1],FL2FX_SGL(0.0163f)); 19722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineLevel = pSineLevel[0]; 19732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (pSineLevel[0]!=FL2FXCONST_DBL(0.0f)) tone_count++; 19752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else if (!noNoiseFlag) { 19762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add noisefloor to the amplified signal */ 19772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index &= (SBR_NF_NO_RANDOM_VAL - 1); 19782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal = signalReal + (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4); 19792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 19812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!(harmIndex&0x1)) { 19822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 0,2 */ 19832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal = signalReal + ( (sineSign) ? -sineLevel : sineLevel); 19842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 19862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* harmIndex 1,3 in combination with freqInvFlag */ 19872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(tone_count <= 16){ 19882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (freqInvFlag) { 19892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal - sineLevelPrev; 19902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (noSubbands + lowSubband < 63) 19912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal = *ptrReal + fMultDiv2(C1, sineLevel); 19922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 19942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal + sineLevelPrev; 19952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (noSubbands + lowSubband < 63) 19962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal = *ptrReal - fMultDiv2(C1, sineLevel); 19972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 19992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else *ptrReal = signalReal; 20002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrHarmIndex = (harmIndex + 1) & 3; 20032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1); 20042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 2005203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivistatic void adjustTimeSlotHQ( 2006203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */ 2007203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */ 20082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, 20092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project ENV_CALC_NRGS* nrgs, 20102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ 20112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noSubbands, /*!< Number of QMF subbands */ 20122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int scale_change, /*!< Number of bits to shift adjusted samples */ 20132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL smooth_ratio, /*!< Impact of last envelope */ 20142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noNoiseFlag, /*!< Start index to random number array */ 20152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */ 20162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 20172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */ 20192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *RESTRICT noiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */ 20202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */ 20212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *RESTRICT filtBuffer = h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */ 20232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL *RESTRICT filtBufferNoise = h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */ 20242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *RESTRICT ptrHarmIndex =&h_sbr_cal_env->harmIndex; /*!< Harmonic index */ 20252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int *RESTRICT ptrPhaseIndex =&h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */ 20262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int k; 20282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL signalReal, signalImag; 20292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL noiseReal, noiseImag; 20302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL smoothedGain, smoothedNoise; 20312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_SGL direct_ratio = /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio; 20322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int index = *ptrPhaseIndex; 20332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR harmIndex = *ptrHarmIndex; 20342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project register int freqInvFlag = (lowSubband & 1); 20352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project FIXP_DBL sineLevel; 20362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int shift; 20372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrPhaseIndex = (index+noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1); 20392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrHarmIndex = (harmIndex + 1) & 3; 20402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 20422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Possible optimization: 20432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smooth_ratio and harmIndex stay constant during the loop. 20442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project It might be faster to include a separate loop in each path. 20452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the check for smooth_ratio is now outside the loop and the workload 20472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project of the whole function decreased by about 20 % 20482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 20492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project filtBufferNoiseShift += 1; /* due to later use of fMultDiv2 instead of fMult */ 20512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (filtBufferNoiseShift<0) 20522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = fixMin(DFRACT_BITS-1,-filtBufferNoiseShift); 20532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 20542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shift = fixMin(DFRACT_BITS-1, filtBufferNoiseShift); 20552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (smooth_ratio > FL2FXCONST_SGL(0.0f)) { 20572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) { 20592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 20602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Smoothing: The old envelope has been bufferd and a certain ratio 20612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project of the old gains and noise levels is used. 20622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 20632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smoothedGain = fMult(smooth_ratio,filtBuffer[k]) + 20652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fMult(direct_ratio,gain[k]); 20662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (filtBufferNoiseShift<0) { 20682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smoothedNoise = (fMultDiv2(smooth_ratio,filtBufferNoise[k])>>shift) + 20692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fMult(direct_ratio,noiseLevel[k]); 20702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 20722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smoothedNoise = (fMultDiv2(smooth_ratio,filtBufferNoise[k])<<shift) + 20732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project fMult(direct_ratio,noiseLevel[k]); 20742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 20752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 20772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project The next 2 multiplications constitute the actual envelope adjustment 20782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project of the signal and should be carried out with full accuracy 20792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project (supplying #DFRACT_BITS valid bits). 20802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */ 20812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal = fMultDiv2(*ptrReal,smoothedGain)<<((int)scale_change); 20822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag = fMultDiv2(*ptrImag,smoothedGain)<<((int)scale_change); 20832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index++; 20852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (pSineLevel[k] != FL2FXCONST_DBL(0.0f)) { 20872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project sineLevel = pSineLevel[k]; 20882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 20892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch(harmIndex) { 20902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 0: 20912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = (signalReal + sineLevel); 20922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag); 20932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 20942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 2: 20952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = (signalReal - sineLevel); 20962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag); 20972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 20982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 1: 20992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = (signalReal); 21002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (freqInvFlag) 21012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag - sineLevel); 21022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 21032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag + sineLevel); 21042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 21052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 3: 21062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 21072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (freqInvFlag) 21082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag + sineLevel); 21092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 21102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag - sineLevel); 21112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 21122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 21152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (noNoiseFlag) { 21162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Just the amplified signal is saved */ 21172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = (signalReal); 21182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag); 21192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else { 21212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add noisefloor to the amplified signal */ 21222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index &= (SBR_NF_NO_RANDOM_VAL - 1); 21232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noiseReal = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise)<<4; 21242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noiseImag = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise)<<4; 21252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = (signalReal + noiseReal); 21262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = (signalImag + noiseImag); 21272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project freqInvFlag ^= 1; 21302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 21342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 21352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k=0; k<noSubbands; k++) 21362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 21372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smoothedGain = gain[k]; 21382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change; 21392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change; 21402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index++; 21422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if ((sineLevel = pSineLevel[k]) != FL2FXCONST_DBL(0.0f)) 21442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 21452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project switch (harmIndex) 21462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 21472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 0: 21482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += sineLevel; 21492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 21502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 1: 21512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (freqInvFlag) 21522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag -= sineLevel; 21532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 21542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag += sineLevel; 21552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 21562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 2: 21572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal -= sineLevel; 21582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 21592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project case 3: 21602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (freqInvFlag) 21612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag += sineLevel; 21622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 21632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag -= sineLevel; 21642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 21652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project else 21682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 21692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (noNoiseFlag == 0) 21702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project { 21712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Add noisefloor to the amplified signal */ 21722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project smoothedNoise = noiseLevel[k]; 21732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project index &= (SBR_NF_NO_RANDOM_VAL - 1); 21742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noiseReal = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise); 21752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project noiseImag = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise); 21762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalReal += noiseReal<<4; 21772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project signalImag += noiseImag<<4; 21782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrReal++ = signalReal; 21812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *ptrImag++ = signalImag; 21822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project freqInvFlag ^= 1; 21842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 21862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 21872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*! 21902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \brief Reset limiter bands. 21912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project Build frequency band table for the gain limiter dependent on 21932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project the previously generated transposer patch areas. 21942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 21952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project \return SBRDEC_OK if ok, SBRDEC_UNSUPPORTED_CONFIG on error 21962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/ 21972228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectSBR_ERROR 21982228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QMF channels */ 21992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *noLimiterBands, /*!< Resulting number of limiter band */ 22002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR *freqBandTable, /*!< Table with possible band borders */ 22012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noFreqBands, /*!< Number of bands in freqBandTable */ 22022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project const PATCH_PARAM *patchParam, /*!< Transposer patch parameters */ 22032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int noPatches, /*!< Number of transposer patches */ 22042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int limiterBands) /*!< Selected 'band density' from bitstream */ 22052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{ 22062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int i, k, isPatchBorder[2], loLimIndex, hiLimIndex, tempNoLim, nBands; 22072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1]; 22082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int patchBorders[MAX_NUM_PATCHES + 1]; 22092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int kx, k2; 22102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int lowSubband = freqBandTable[0]; 22122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project int highSubband = freqBandTable[noFreqBands]; 22132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 1 limiter band. */ 22152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if(limiterBands == 0) { 22162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project limiterBandTable[0] = 0; 22172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project limiterBandTable[1] = highSubband - lowSubband; 22182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nBands = 1; 22192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } else { 22202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (i = 0; i < noPatches; i++) { 22212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project patchBorders[i] = patchParam[i].guardStartBand - lowSubband; 22222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project patchBorders[i] = highSubband - lowSubband; 22242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */ 22262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = 0; k <= noFreqBands; k++) { 22272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project workLimiterBandTable[k] = freqBandTable[k] - lowSubband; 22282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = 1; k < noPatches; k++) { 22302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project workLimiterBandTable[noFreqBands + k] = patchBorders[k]; 22312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project tempNoLim = nBands = noFreqBands + noPatches - 1; 22342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shellsort(workLimiterBandTable, tempNoLim + 1); 22352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project loLimIndex = 0; 22372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hiLimIndex = 1; 22382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project while (hiLimIndex <= tempNoLim) { 2241203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi FIXP_DBL div_m, oct_m, temp; 2242203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi INT div_e = 0, oct_e = 0, temp_e = 0; 2243203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 22442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project k2 = workLimiterBandTable[hiLimIndex] + lowSubband; 22452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project kx = workLimiterBandTable[loLimIndex] + lowSubband; 22462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2247203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi div_m = fDivNorm(k2, kx, &div_e); 2248203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 2249203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi /* calculate number of octaves */ 2250203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi oct_m = fLog2(div_m, div_e, &oct_e); 2251203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 2252203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi /* multiply with limiterbands per octave */ 2253203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi /* values 1, 1.2, 2, 3 -> scale factor of 2 */ 2254203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi temp = fMultNorm(oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands], &temp_e); 2255203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 2256203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi /* overall scale factor of temp ist addition of scalefactors from log2 calculation, 2257203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi limiter bands scalefactor (2) and limiter bands multiplication */ 2258203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi temp_e += oct_e + 2; 2259203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi 2260203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi /* div can be a maximum of 64 (k2 = 64 and kx = 1) 2261203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi -> oct can be a maximum of 6 2262203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi -> temp can be a maximum of 18 (as limiterBandsPerOctoave is a maximum factor of 3) 2263203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi -> we need a scale factor of 5 for comparisson 2264203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi */ 2265203e3f28fbebec7011342017fafc2a0bda0ce530Jean-Michel Trivi if (temp >> (5 - temp_e) < FL2FXCONST_DBL (0.49f) >> 5) { 22662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 22672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (workLimiterBandTable[hiLimIndex] == workLimiterBandTable[loLimIndex]) { 22682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project workLimiterBandTable[hiLimIndex] = highSubband; 22692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nBands--; 22702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hiLimIndex++; 22712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project continue; 22722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isPatchBorder[0] = isPatchBorder[1] = 0; 22742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = 0; k <= noPatches; k++) { 22752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (workLimiterBandTable[hiLimIndex] == patchBorders[k]) { 22762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isPatchBorder[1] = 1; 22772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 22782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!isPatchBorder[1]) { 22812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project workLimiterBandTable[hiLimIndex] = highSubband; 22822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nBands--; 22832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hiLimIndex++; 22842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project continue; 22852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = 0; k <= noPatches; k++) { 22872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (workLimiterBandTable[loLimIndex] == patchBorders[k]) { 22882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project isPatchBorder[0] = 1; 22892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project break; 22902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if (!isPatchBorder[0]) { 22932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project workLimiterBandTable[loLimIndex] = highSubband; 22942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project nBands--; 22952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 22972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project loLimIndex = hiLimIndex; 22982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project hiLimIndex++; 22992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 23002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 23012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project shellsort(workLimiterBandTable, tempNoLim + 1); 23022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 23032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Test if algorithm exceeded maximum allowed limiterbands */ 23042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project if( nBands > MAX_NUM_LIMITERS || nBands <= 0) { 23052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return SBRDEC_UNSUPPORTED_CONFIG; 23062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 23072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 23082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project /* Copy limiterbands from working buffer into final destination */ 23092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project for (k = 0; k <= nBands; k++) { 23102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project limiterBandTable[k] = workLimiterBandTable[k]; 23112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 23122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project } 23132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *noLimiterBands = nBands; 23142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 23152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project return SBRDEC_OK; 23162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project} 23172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 2318