12228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
22228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* -----------------------------------------------------------------------------------------------------------
32228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectSoftware License for The Fraunhofer FDK AAC Codec Library for Android
42228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
54f0d97057c5c640b25518358886f8c47da9fc052Jean-Michel Trivi� Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
62228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  All rights reserved.
72228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
82228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1.    INTRODUCTION
92228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThe Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthe MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
112228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThis FDK AAC Codec software is intended to be used on a wide variety of Android devices.
122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
132228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectaudio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectindependent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectof the MPEG specifications.
172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
182228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectPatent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectmay be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectindividually for the purpose of encoding or decoding bit streams in products that are compliant with
212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthe ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthese patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectsoftware may already be covered under those patent licenses when it is used for those licensed purposes only.
242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
252228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectCommercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectare also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectapplications information and documentation.
282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project2.    COPYRIGHT LICENSE
302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
312228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectRedistribution and use in source and binary forms, with or without modification, are permitted without
322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectpayment of copyright license fees provided that you satisfy the following conditions:
332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
342228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must retain the complete text of this software license in redistributions of the FDK AAC Codec or
352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectyour modifications thereto in source code form.
362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
372228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must retain the complete text of this software license in the documentation and/or other materials
382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectprovided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
392228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must make available free of charge copies of the complete source code of the FDK AAC Codec and your
402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectmodifications thereto to recipients of copies in binary form.
412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
422228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThe name of Fraunhofer may not be used to endorse or promote products derived from this library without
432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectprior written permission.
442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
452228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectsoftware or your modifications thereto.
472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
482228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYour modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectand the date of any change. For modified versions of the FDK AAC Codec, the term
502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project3.    NO PATENT LICENSE
542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
552228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectNO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
562228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectrespect to this software.
582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
592228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectby appropriate patent licenses.
612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project4.    DISCLAIMER
632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
642228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThis FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectof merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
672228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectCONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectincluding but not limited to procurement of substitute goods or services; loss of use, data, or profits,
692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projector business interruption, however caused and on any theory of liability, whether in contract, strict
702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectliability, or tort (including negligence), arising in any way out of the use of this software, even if
712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectadvised of the possibility of such damage.
722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project5.    CONTACT INFORMATION
742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
752228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFraunhofer Institute for Integrated Circuits IIS
762228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAttention: Audio and Multimedia Departments - FDK AAC LL
772228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAm Wolfsmantel 33
782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project91058 Erlangen, Germany
792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectwww.iis.fraunhofer.de/amm
812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectamm-info@iis.fraunhofer.de
822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project----------------------------------------------------------------------------------------------------------- */
832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \file
862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief  envelope decoding
872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  This module provides envelope decoding and error concealment algorithms. The main
882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  entry point is decodeSbrData().
892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \sa decodeSbrData(),\ref documentationOverview
912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "env_dec.h"
942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "env_extr.h"
962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "transcendent.h"
972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "genericStds.h"
992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void decodeEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData,
1022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            HANDLE_SBR_FRAME_DATA h_sbr_data,
1032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            HANDLE_SBR_PREV_FRAME_DATA h_prev_data,
1042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            HANDLE_SBR_PREV_FRAME_DATA h_prev_data_otherChannel);
1052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void sbr_envelope_unmapping (HANDLE_SBR_HEADER_DATA hHeaderData,
1062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    HANDLE_SBR_FRAME_DATA h_data_left,
1072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    HANDLE_SBR_FRAME_DATA h_data_right);
1082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void requantizeEnvelopeData (HANDLE_SBR_FRAME_DATA h_sbr_data,
1092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    int ampResolution);
1102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void deltaToLinearPcmEnvelopeDecoding (HANDLE_SBR_HEADER_DATA hHeaderData,
1112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                              HANDLE_SBR_FRAME_DATA h_sbr_data,
1122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                              HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
1132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void decodeNoiseFloorlevels (HANDLE_SBR_HEADER_DATA hHeaderData,
1142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    HANDLE_SBR_FRAME_DATA h_sbr_data,
1152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
1162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void timeCompensateFirstEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData,
1172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                         HANDLE_SBR_FRAME_DATA h_sbr_data,
1182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                         HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
1192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic int checkEnvelopeData (HANDLE_SBR_HEADER_DATA hHeaderData,
1202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              HANDLE_SBR_FRAME_DATA h_sbr_data,
1212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              HANDLE_SBR_PREV_FRAME_DATA h_prev_data);
1222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define SBR_ENERGY_PAN_OFFSET   (12 << ENV_EXP_FRACT)
1262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define SBR_MAX_ENERGY          (35 << ENV_EXP_FRACT)
1272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define DECAY                   ( 1 << ENV_EXP_FRACT)
1292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#if ENV_EXP_FRACT
1312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define DECAY_COUPLING          ( 1 << (ENV_EXP_FRACT-1) ) /*!< corresponds to a value of 0.5 */
1322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#else
1332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define DECAY_COUPLING            1  /*!< If the energy data is not shifted, use 1 instead of 0.5 */
1342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
1352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
1382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief  Convert table index
1392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
1402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic int indexLow2High(int offset, /*!< mapping factor */
1412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         int index,  /*!< index to scalefactor band */
1422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         int res)    /*!< frequency resolution */
1432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if(res == 0)
1452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
1462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (offset >= 0)
1472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
1482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (index < offset)
1492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          return(index);
1502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        else
1512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          return(2*index - offset);
1522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
1532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    else
1542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
1552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        offset = -offset;
1562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (index < offset)
1572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          return(2*index+index);
1582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        else
1592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          return(2*index + offset);
1602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
1612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
1622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  else
1632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return(index);
1642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
1682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief  Update previous envelope value for delta-coding
1692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The current envelope values needs to be stored for delta-coding
1712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  in the next frame.  The stored envelope is always represented with
1722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  the high frequency resolution.  If the current envelope uses the
1732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  low frequency resolution, the energy value will be mapped to the
1742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  corresponding high-res bands.
1752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
1762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void mapLowResEnergyVal(FIXP_SGL currVal,  /*!< current energy value */
1772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               FIXP_SGL* prevData,/*!< pointer to previous data vector */
1782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               int offset,      /*!< mapping factor */
1792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               int index,       /*!< index to scalefactor band */
1802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               int res)         /*!< frequeny resolution */
1812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if(res == 0)
1832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
1842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (offset >= 0)
1852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
1862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if(index < offset)
1872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            prevData[index] = currVal;
1882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        else
1892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        {
1902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            prevData[2*index - offset] = currVal;
1912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            prevData[2*index+1 - offset] = currVal;
1922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
1932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
1942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    else
1952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
1962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        offset = -offset;
1972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (index < offset)
1982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        {
1992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            prevData[3*index] = currVal;
2002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            prevData[3*index+1] = currVal;
2012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            prevData[3*index+2] = currVal;
2022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
2032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        else
2042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        {
2052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            prevData[2*index + offset] = currVal;
2062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            prevData[2*index + 1 + offset] = currVal;
2072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
2082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
2092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  else
2112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    prevData[index] = currVal;
2122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
2132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
2172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief    Convert raw envelope and noisefloor data to energy levels
2182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  This function is being called by sbrDecoder_ParseElement() and provides two important algorithms:
2202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  First the function decodes envelopes and noise floor levels as described in requantizeEnvelopeData()
2222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  and sbr_envelope_unmapping(). The function also implements concealment algorithms in case there are errors
2232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  within the sbr data. For both operations fractional arithmetic is used.
2242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Therefore you might encounter different output values on your target
2252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  system compared to the reference implementation.
2262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
2272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid
2282228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectdecodeSbrData (HANDLE_SBR_HEADER_DATA hHeaderData,          /*!< Static control data */
2292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project               HANDLE_SBR_FRAME_DATA h_data_left,           /*!< pointer to left channel frame data */
2302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project               HANDLE_SBR_PREV_FRAME_DATA h_prev_data_left, /*!< pointer to left channel previous frame data */
2312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project               HANDLE_SBR_FRAME_DATA h_data_right,          /*!< pointer to right channel frame data */
2322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project               HANDLE_SBR_PREV_FRAME_DATA h_prev_data_right)/*!< pointer to right channel previous frame data */
2332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
2342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_SGL tempSfbNrgPrev[MAX_FREQ_COEFFS];
2352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int errLeft;
2362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Save previous energy values to be able to reuse them later for concealment. */
2382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKmemcpy (tempSfbNrgPrev, h_prev_data_left->sfb_nrg_prev, MAX_FREQ_COEFFS * sizeof(FIXP_SGL));
2392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  decodeEnvelope (hHeaderData, h_data_left, h_prev_data_left, h_prev_data_right);
2412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  decodeNoiseFloorlevels (hHeaderData, h_data_left, h_prev_data_left);
2422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if(h_data_right != NULL) {
2442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    errLeft = hHeaderData->frameErrorFlag;
2452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    decodeEnvelope (hHeaderData, h_data_right, h_prev_data_right, h_prev_data_left);
2462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    decodeNoiseFloorlevels (hHeaderData, h_data_right, h_prev_data_right);
2472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (!errLeft && hHeaderData->frameErrorFlag) {
2492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* If an error occurs in the right channel where the left channel seemed ok,
2502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project         we apply concealment also on the left channel. This ensures that the coupling
2512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project         modes of both channels match and that we have the same number of envelopes in
2522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project         coupling mode.
2532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project         However, as the left channel has already been processed before, the resulting
2542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project         energy levels are not the same as if the left channel had been concealed
2552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project         during the first call of decodeEnvelope().
2562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      */
2572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* Restore previous energy values for concealment, because the values have been
2582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project         overwritten by the first call of decodeEnvelope(). */
2592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      FDKmemcpy (h_prev_data_left->sfb_nrg_prev, tempSfbNrgPrev, MAX_FREQ_COEFFS * sizeof(FIXP_SGL));
2602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* Do concealment */
2612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      decodeEnvelope (hHeaderData, h_data_left, h_prev_data_left, h_prev_data_right);
2622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
2632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (h_data_left->coupling) {
2652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      sbr_envelope_unmapping (hHeaderData, h_data_left, h_data_right);
2662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
2672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Display the data for debugging: */
2702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
2712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
2742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief   Convert from coupled channels to independent L/R data
2752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
2762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
2772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectsbr_envelope_unmapping (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
2782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        HANDLE_SBR_FRAME_DATA h_data_left,  /*!< pointer to left channel */
2792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        HANDLE_SBR_FRAME_DATA h_data_right) /*!< pointer to right channel */
2802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
2812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
2822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_SGL tempL_m, tempR_m, tempRplus1_m, newL_m, newR_m;
2832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  SCHAR   tempL_e, tempR_e, tempRplus1_e, newL_e, newR_e;
2842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* 1. Unmap (already dequantized) coupled envelope energies */
2872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 0; i < h_data_left->nScaleFactors; i++) {
2892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tempR_m = (FIXP_SGL)((LONG)h_data_right->iEnvelope[i] & MASK_M);
2902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tempR_e = (SCHAR)((LONG)h_data_right->iEnvelope[i] & MASK_E);
2912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tempR_e -= (18 + NRG_EXP_OFFSET);  /* -18 = ld(UNMAPPING_SCALE / h_data_right->nChannels) */
2932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tempL_m = (FIXP_SGL)((LONG)h_data_left->iEnvelope[i] & MASK_M);
2942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tempL_e = (SCHAR)((LONG)h_data_left->iEnvelope[i] & MASK_E);
2952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tempL_e -= NRG_EXP_OFFSET;
2972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Calculate tempRight+1 */
2992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_add_MantExp( tempR_m, tempR_e,
3002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                     FL2FXCONST_SGL(0.5f), 1,  /* 1.0 */
3012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                     &tempRplus1_m, &tempRplus1_e);
3022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_divide_MantExp( tempL_m, tempL_e+1,  /*  2 * tempLeft */
3042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       tempRplus1_m, tempRplus1_e,
3052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       &newR_m, &newR_e );
3062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) {
3082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      newR_m >>= 1;
3092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      newR_e += 1;
3102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
3112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    newL_m = FX_DBL2FX_SGL(fMult(tempR_m,newR_m));
3132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    newL_e = tempR_e + newR_e;
3142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    h_data_right->iEnvelope[i] = ((FIXP_SGL)((SHORT)(FIXP_SGL)(newR_m + ROUNDING) & MASK_M)) +
3162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                  (FIXP_SGL)((SHORT)(FIXP_SGL)(newR_e + NRG_EXP_OFFSET) & MASK_E);
3172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    h_data_left->iEnvelope[i] =  ((FIXP_SGL)((SHORT)(FIXP_SGL)(newL_m + ROUNDING) & MASK_M)) +
3182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                  (FIXP_SGL)((SHORT)(FIXP_SGL)(newL_e + NRG_EXP_OFFSET) & MASK_E);
3192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
3202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* 2. Dequantize and unmap coupled noise floor levels */
3222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 0; i < hHeaderData->freqBandData.nNfb * h_data_left->frameInfo.nNoiseEnvelopes; i++) {
3242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tempL_e = (SCHAR)(6 - (LONG)h_data_left->sbrNoiseFloorLevel[i]);
3262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tempR_e = (SCHAR)((LONG)h_data_right->sbrNoiseFloorLevel[i] - 12) /*SBR_ENERGY_PAN_OFFSET*/;
3272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Calculate tempR+1 */
3292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_add_MantExp( FL2FXCONST_SGL(0.5f), 1+tempR_e, /* tempR */
3302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                     FL2FXCONST_SGL(0.5f), 1,         /*  1.0  */
3312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                     &tempRplus1_m, &tempRplus1_e);
3322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Calculate 2*tempLeft/(tempR+1) */
3342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_divide_MantExp( FL2FXCONST_SGL(0.5f), tempL_e+2,  /*  2 * tempLeft */
3352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       tempRplus1_m, tempRplus1_e,
3362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       &newR_m, &newR_e );
3372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) {
3392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      newR_m >>= 1;
3402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      newR_e += 1;
3412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } */
3422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* L = tempR * R */
3442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    newL_m = newR_m;
3452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    newL_e = newR_e + tempR_e;
3462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    h_data_right->sbrNoiseFloorLevel[i] = ((FIXP_SGL)((SHORT)(FIXP_SGL)(newR_m + ROUNDING) & MASK_M)) +
3472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           (FIXP_SGL)((SHORT)(FIXP_SGL)(newR_e + NOISE_EXP_OFFSET) & MASK_E);
3482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    h_data_left->sbrNoiseFloorLevel[i] =  ((FIXP_SGL)((SHORT)(FIXP_SGL)(newL_m + ROUNDING) & MASK_M)) +
3492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           (FIXP_SGL)((SHORT)(FIXP_SGL)(newL_e + NOISE_EXP_OFFSET) & MASK_E);
3502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
3512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
3522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
3552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief    Simple alternative to the real SBR concealment
3562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  If the real frameInfo is not available due to a frame loss, a replacement will
3582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  be constructed with 1 envelope spanning the whole frame (FIX-FIX).
3592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The delta-coded energies are set to negative values, resulting in a fade-down.
3602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  In case of coupling, the balance-channel will move towards the center.
3612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
3622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
3632228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectleanSbrConcealment(HANDLE_SBR_HEADER_DATA hHeaderData,     /*!< Static control data */
3642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   HANDLE_SBR_FRAME_DATA  h_sbr_data,      /*!< pointer to current data */
3652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   HANDLE_SBR_PREV_FRAME_DATA h_prev_data  /*!< pointer to data of last frame */
3662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   )
3672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
3682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_SGL target;  /* targeted level for sfb_nrg_prev during fade-down */
3692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_SGL step;    /* speed of fade */
3702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
3712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int currentStartPos = h_prev_data->stopPos - hHeaderData->numberTimeSlots;
3732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int currentStopPos = hHeaderData->numberTimeSlots;
3742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Use some settings of the previous frame */
3772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_sbr_data->ampResolutionCurrentFrame = h_prev_data->ampRes;
3782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_sbr_data->coupling = h_prev_data->coupling;
3792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for(i=0;i<MAX_INVF_BANDS;i++)
3802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    h_sbr_data->sbr_invf_mode[i] = h_prev_data->sbr_invf_mode[i];
3812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Generate concealing control data */
3832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_sbr_data->frameInfo.nEnvelopes = 1;
3852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_sbr_data->frameInfo.borders[0] = currentStartPos;
3862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_sbr_data->frameInfo.borders[1] = currentStopPos;
3872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_sbr_data->frameInfo.freqRes[0] = 1;
3882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_sbr_data->frameInfo.tranEnv = -1;  /* no transient */
3892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_sbr_data->frameInfo.nNoiseEnvelopes = 1;
3902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_sbr_data->frameInfo.bordersNoise[0] = currentStartPos;
3912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_sbr_data->frameInfo.bordersNoise[1] = currentStopPos;
3922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_sbr_data->nScaleFactors = hHeaderData->freqBandData.nSfb[1];
3942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Generate fake envelope data */
3962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_sbr_data->domain_vec[0] = 1;
3982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (h_sbr_data->coupling == COUPLING_BAL) {
4002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    target = (FIXP_SGL)SBR_ENERGY_PAN_OFFSET;
4012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    step = (FIXP_SGL)DECAY_COUPLING;
4022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
4032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  else {
4042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    target = FL2FXCONST_SGL(0.0f);
4052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    step   = (FIXP_SGL)DECAY;
4062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
4072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (hHeaderData->bs_info.ampResolution == 0) {
4082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    target <<= 1;
4092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    step   <<= 1;
4102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
4112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i < h_sbr_data->nScaleFactors; i++) {
4132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (h_prev_data->sfb_nrg_prev[i] > target)
4142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      h_sbr_data->iEnvelope[i] = -step;
4152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    else
4162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      h_sbr_data->iEnvelope[i] = step;
4172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
4182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Noisefloor levels are always cleared ... */
4202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  h_sbr_data->domain_vec_noise[0] = 1;
4222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i < hHeaderData->freqBandData.nNfb; i++)
4232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    h_sbr_data->sbrNoiseFloorLevel[i] = FL2FXCONST_SGL(0.0f);
4242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* ... and so are the sines */
4262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKmemclear(h_sbr_data->addHarmonics, MAX_FREQ_COEFFS);
4272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
4282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
4312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief   Build reference energies and noise levels from bitstream elements
4322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
4332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
4342228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectdecodeEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData,     /*!< Static control data */
4352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                HANDLE_SBR_FRAME_DATA  h_sbr_data,      /*!< pointer to current data */
4362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                HANDLE_SBR_PREV_FRAME_DATA h_prev_data, /*!< pointer to data of last frame */
4372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                HANDLE_SBR_PREV_FRAME_DATA otherChannel /*!< other channel's last frame data */
4382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                )
4392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
4402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
4412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int fFrameError = hHeaderData->frameErrorFlag;
4422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_SGL tempSfbNrgPrev[MAX_FREQ_COEFFS];
4432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (!fFrameError) {
4452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /*
4462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      To avoid distortions after bad frames, set the error flag if delta coding in time occurs.
4472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      However, SBR can take a little longer to come up again.
4482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    */
4492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if ( h_prev_data->frameErrorFlag ) {
4502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (h_sbr_data->domain_vec[0] != 0) {
4512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        fFrameError = 1;
4522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
4532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } else {
4542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* Check that the previous stop position and the current start position match.
4552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project         (Could be done in checkFrameInfo(), but the previous frame data is not available there) */
4562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if ( h_sbr_data->frameInfo.borders[0] != h_prev_data->stopPos - hHeaderData->numberTimeSlots ) {
4572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* Both the previous as well as the current frame are flagged to be ok, but they do not match! */
4582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (h_sbr_data->domain_vec[0] == 1) {
4592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          /* Prefer concealment over delta-time coding between the mismatching frames */
4602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          fFrameError = 1;
4612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
4622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        else {
4632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          /* Close the gap in time by triggering timeCompensateFirstEnvelope() */
4642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          fFrameError = 1;
4652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
4662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
4672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
4682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
4692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (fFrameError)       /* Error is detected */
4722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
4732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      leanSbrConcealment(hHeaderData,
4742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         h_sbr_data,
4752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         h_prev_data);
4762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* decode the envelope data to linear PCM */
4782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      deltaToLinearPcmEnvelopeDecoding (hHeaderData, h_sbr_data, h_prev_data);
4792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
4802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  else                          /*Do a temporary dummy decoding and check that the envelope values are within limits */
4812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
4822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (h_prev_data->frameErrorFlag) {
4832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        timeCompensateFirstEnvelope (hHeaderData, h_sbr_data, h_prev_data);
4842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (h_sbr_data->coupling != h_prev_data->coupling) {
4852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          /*
4862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            Coupling mode has changed during concealment.
4872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project             The stored energy levels need to be converted.
4882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project           */
4892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          for (i = 0; i < hHeaderData->freqBandData.nSfb[1]; i++) {
4902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* Former Level-Channel will be used for both channels */
4912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if (h_prev_data->coupling == COUPLING_BAL)
4922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              h_prev_data->sfb_nrg_prev[i] = otherChannel->sfb_nrg_prev[i];
4932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* Former L/R will be combined as the new Level-Channel */
4942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            else if (h_sbr_data->coupling == COUPLING_LEVEL)
4952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              h_prev_data->sfb_nrg_prev[i] = (h_prev_data->sfb_nrg_prev[i] + otherChannel->sfb_nrg_prev[i]) >> 1;
4962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            else if (h_sbr_data->coupling == COUPLING_BAL)
4972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              h_prev_data->sfb_nrg_prev[i] = (FIXP_SGL)SBR_ENERGY_PAN_OFFSET;
4982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
4992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
5002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
5012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      FDKmemcpy (tempSfbNrgPrev, h_prev_data->sfb_nrg_prev,
5022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              MAX_FREQ_COEFFS * sizeof (FIXP_SGL));
5032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      deltaToLinearPcmEnvelopeDecoding (hHeaderData, h_sbr_data, h_prev_data);
5052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      fFrameError = checkEnvelopeData (hHeaderData, h_sbr_data, h_prev_data);
5072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (fFrameError)
5092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        {
5102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          hHeaderData->frameErrorFlag = 1;
5112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          FDKmemcpy (h_prev_data->sfb_nrg_prev, tempSfbNrgPrev,
5122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                  MAX_FREQ_COEFFS * sizeof (FIXP_SGL));
5132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          decodeEnvelope (hHeaderData, h_sbr_data, h_prev_data, otherChannel);
5142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          return;
5152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
5162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  requantizeEnvelopeData (h_sbr_data, h_sbr_data->ampResolutionCurrentFrame);
5192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  hHeaderData->frameErrorFlag = fFrameError;
5212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
5222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
5252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief   Verify that envelope energies are within the allowed range
5262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \return  0 if all is fine, 1 if an envelope value was too high
5272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
5282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic int
5292228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectcheckEnvelopeData (HANDLE_SBR_HEADER_DATA hHeaderData,     /*!< Static control data */
5302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   HANDLE_SBR_FRAME_DATA h_sbr_data,       /*!< pointer to current data */
5312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   HANDLE_SBR_PREV_FRAME_DATA h_prev_data  /*!< pointer to data of last frame */
5322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   )
5332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
5342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_SGL *iEnvelope = h_sbr_data->iEnvelope;
5352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_SGL *sfb_nrg_prev = h_prev_data->sfb_nrg_prev;
5362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int    i = 0, errorFlag = 0;
5372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_SGL sbr_max_energy =
5382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    (h_sbr_data->ampResolutionCurrentFrame == 1) ? SBR_MAX_ENERGY : (SBR_MAX_ENERGY << 1);
5392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /*
5412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    Range check for current energies
5422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  */
5432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 0; i < h_sbr_data->nScaleFactors; i++) {
5442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (iEnvelope[i] > sbr_max_energy) {
5452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      errorFlag = 1;
5462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (iEnvelope[i] < FL2FXCONST_SGL(0.0f)) {
5482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      errorFlag = 1;
5492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* iEnvelope[i] = FL2FXCONST_SGL(0.0f); */
5502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
5522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /*
5542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    Range check for previous energies
5552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  */
5562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 0; i < hHeaderData->freqBandData.nSfb[1]; i++) {
5572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sfb_nrg_prev[i] = fixMax(sfb_nrg_prev[i], FL2FXCONST_SGL(0.0f));
5582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sfb_nrg_prev[i] = fixMin(sfb_nrg_prev[i], sbr_max_energy);
5592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
5602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return (errorFlag);
5622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
5632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
5662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief   Verify that the noise levels are within the allowed range
5672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The function is equivalent to checkEnvelopeData().
5692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  When the noise-levels are being decoded, it is already too late for
5702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  concealment. Therefore the noise levels are simply limited here.
5712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
5722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
5732228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectlimitNoiseLevels(HANDLE_SBR_HEADER_DATA hHeaderData,     /*!< Static control data */
5742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                 HANDLE_SBR_FRAME_DATA h_sbr_data)       /*!< pointer to current data */
5752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
5762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
5772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int nNfb = hHeaderData->freqBandData.nNfb;
5782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /*
5802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    Set range limits. The exact values depend on the coupling mode.
5812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    However this limitation is primarily intended to avoid unlimited
5822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    accumulation of the delta-coded noise levels.
5832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  */
5842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  #define lowerLimit   ((FIXP_SGL)0)     /* lowerLimit actually refers to the _highest_ noise energy */
5852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  #define upperLimit   ((FIXP_SGL)35)    /* upperLimit actually refers to the _lowest_ noise energy */
5862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /*
5882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    Range check for current noise levels
5892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  */
5902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 0; i < h_sbr_data->frameInfo.nNoiseEnvelopes * nNfb; i++) {
5912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    h_sbr_data->sbrNoiseFloorLevel[i] = fixMin(h_sbr_data->sbrNoiseFloorLevel[i], upperLimit);
5922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    h_sbr_data->sbrNoiseFloorLevel[i] = fixMax(h_sbr_data->sbrNoiseFloorLevel[i], lowerLimit);
5932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
5942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
5952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
5982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief   Compensate for the wrong timing that might occur after a frame error.
5992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
6002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
6012228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjecttimeCompensateFirstEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
6022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             HANDLE_SBR_FRAME_DATA h_sbr_data,   /*!< pointer to actual data */
6032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             HANDLE_SBR_PREV_FRAME_DATA h_prev_data)  /*!< pointer to data of last frame */
6042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
6052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i, nScalefactors;
6062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FRAME_INFO *pFrameInfo = &h_sbr_data->frameInfo;
6072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  UCHAR *nSfb = hHeaderData->freqBandData.nSfb;
6082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int estimatedStartPos = h_prev_data->stopPos - hHeaderData->numberTimeSlots;
6092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int refLen, newLen, shift;
6102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_SGL  deltaExp;
6112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Original length of first envelope according to bitstream */
6132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  refLen = pFrameInfo->borders[1] - pFrameInfo->borders[0];
6142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Corrected length of first envelope (concealing can make the first envelope longer) */
6152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  newLen = pFrameInfo->borders[1] - estimatedStartPos;
6162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (newLen <= 0) {
6182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* An envelope length of <= 0 would not work, so we don't use it.
6192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project       May occur if the previous frame was flagged bad due to a mismatch
6202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project       of the old and new frame infos. */
6212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    newLen = refLen;
6222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    estimatedStartPos = pFrameInfo->borders[0];
6232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
6242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  deltaExp = FDK_getNumOctavesDiv8(newLen, refLen);
6262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6275016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  /* Shift by -3 to rescale ld-table, ampRes-1 to enable coarser steps */
6285016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  shift = (FRACT_BITS - 1 - ENV_EXP_FRACT - 1 + h_sbr_data->ampResolutionCurrentFrame - 3);
6292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  deltaExp = deltaExp >> shift;
6302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pFrameInfo->borders[0] = estimatedStartPos;
6312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pFrameInfo->bordersNoise[0] = estimatedStartPos;
6322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (h_sbr_data->coupling != COUPLING_BAL) {
6342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    nScalefactors = (pFrameInfo->freqRes[0]) ? nSfb[1] : nSfb[0];
6352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i = 0; i < nScalefactors; i++)
6372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      h_sbr_data->iEnvelope[i] = h_sbr_data->iEnvelope[i] + deltaExp;
6382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
6392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
6402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
6442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief   Convert each envelope value from logarithmic to linear domain
6452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Energy levels are transmitted in powers of 2, i.e. only the exponent
6472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  is extracted from the bitstream.
6482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  Therefore, normally only integer exponents can occur. However during
6492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  fading (in case of a corrupt bitstream), a fractional part can also
6502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  occur. The data in the array iEnvelope is shifted left by ENV_EXP_FRACT
6512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  compared to an integer representation so that numbers smaller than 1
6522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  can be represented.
6532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  This function calculates a mantissa corresponding to the fractional
6552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  part of the exponent for each reference energy. The array iEnvelope
6562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  is converted in place to save memory. Input and output data must
6572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  be interpreted differently, as shown in the below figure:
6582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \image html  EnvelopeData.png
6602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The data is then used in calculateSbrEnvelope().
6622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
6632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
6642228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectrequantizeEnvelopeData (HANDLE_SBR_FRAME_DATA h_sbr_data, int ampResolution)
6652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
6662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
6672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_SGL mantissa;
6682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int ampShift = 1 - ampResolution;
6692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int exponent;
6702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* In case that ENV_EXP_FRACT is changed to something else but 0 or 8,
6722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project     the initialization of this array has to be adapted!
6732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  */
6742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#if ENV_EXP_FRACT
6752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  static const FIXP_SGL pow2[ENV_EXP_FRACT] =
6762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
6772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 1))), /* 0.7071 */
6782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 2))), /* 0.5946 */
6792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 3))),
6802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 4))),
6812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 5))),
6822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 6))),
6832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 7))),
6842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 8)))  /* 0.5013 */
6852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  };
6862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int bit, mask;
6882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
6892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 0; i < h_sbr_data->nScaleFactors; i++) {
6912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    exponent = (LONG)h_sbr_data->iEnvelope[i];
6922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#if ENV_EXP_FRACT
6942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    exponent = exponent >> ampShift;
6962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    mantissa = 0.5f;
6972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Amplify mantissa according to the fractional part of the
6992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project       exponent (result will be between 0.500000 and 0.999999)
7002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    */
7012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    mask = 1;  /* begin with lowest bit of exponent */
7022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for ( bit=ENV_EXP_FRACT-1; bit>=0; bit-- ) {
7042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (exponent & mask) {
7052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* The current bit of the exponent is set,
7062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project           multiply mantissa with the corresponding factor: */
7072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        mantissa = (FIXP_SGL)( (mantissa * pow2[bit]) << 1);
7082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
7092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* Advance to next bit */
7102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      mask = mask << 1;
7112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
7122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Make integer part of exponent right aligned */
7142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    exponent = exponent >> ENV_EXP_FRACT;
7152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#else
7172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* In case of the high amplitude resolution, 1 bit of the exponent gets lost by the shift.
7182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project       This will be compensated by a mantissa of 0.5*sqrt(2) instead of 0.5 if that bit is 1. */
7192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    mantissa = (exponent & ampShift) ? FL2FXCONST_SGL(0.707106781186548f) : FL2FXCONST_SGL(0.5f);
7202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    exponent = exponent >> ampShift;
7212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
7222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /*
7242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      Mantissa was set to 0.5 (instead of 1.0, therefore increase exponent by 1).
7252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      Multiply by L=nChannels=64 by increasing exponent by another 6.
7262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      => Increase exponent by 7
7272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    */
7282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    exponent += 7 + NRG_EXP_OFFSET;
7292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Combine mantissa and exponent and write back the result */
7312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    h_sbr_data->iEnvelope[i] = (FIXP_SGL)(((LONG)mantissa & MASK_M) | (exponent & MASK_E));
7322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
7342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
7352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
7382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief   Build new reference energies from old ones and delta coded data
7392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
7402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
7412228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectdeltaToLinearPcmEnvelopeDecoding (HANDLE_SBR_HEADER_DATA hHeaderData,     /*!< Static control data */
7422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                  HANDLE_SBR_FRAME_DATA h_sbr_data,       /*!< pointer to current data */
7432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                  HANDLE_SBR_PREV_FRAME_DATA h_prev_data) /*!< pointer to previous data */
7442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
7452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i, domain, no_of_bands, band, freqRes;
7462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_SGL *sfb_nrg_prev = h_prev_data->sfb_nrg_prev;
7482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_SGL *ptr_nrg = h_sbr_data->iEnvelope;
7492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int offset = 2 * hHeaderData->freqBandData.nSfb[0] - hHeaderData->freqBandData.nSfb[1];
7512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 0; i < h_sbr_data->frameInfo.nEnvelopes; i++) {
7532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    domain = h_sbr_data->domain_vec[i];
7542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    freqRes = h_sbr_data->frameInfo.freqRes[i];
7552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_ASSERT(freqRes >= 0 && freqRes <= 1);
7572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    no_of_bands = hHeaderData->freqBandData.nSfb[freqRes];
7592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDK_ASSERT(no_of_bands < (64));
7612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (domain == 0)
7632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
7642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, 0, freqRes);
7652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      ptr_nrg++;
7662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      for (band = 1; band < no_of_bands; band++)
7672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      {
7682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        *ptr_nrg = *ptr_nrg + *(ptr_nrg-1);
7692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, band, freqRes);
7702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        ptr_nrg++;
7712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
7722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
7732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    else
7742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
7752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      for (band = 0; band < no_of_bands; band++)
7762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      {
7772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        *ptr_nrg = *ptr_nrg + sfb_nrg_prev[indexLow2High(offset, band, freqRes)];
7782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, band, freqRes);
7792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        ptr_nrg++;
7802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
7812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
7822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
7832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
7842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
7872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief   Build new noise levels from old ones and delta coded data
7882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
7892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void
7902228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectdecodeNoiseFloorlevels (HANDLE_SBR_HEADER_DATA hHeaderData,     /*!< Static control data */
7912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        HANDLE_SBR_FRAME_DATA h_sbr_data,       /*!< pointer to current data */
7922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        HANDLE_SBR_PREV_FRAME_DATA h_prev_data) /*!< pointer to previous data */
7932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
7942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i;
7952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int nNfb = hHeaderData->freqBandData.nNfb;
7962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int nNoiseFloorEnvelopes = h_sbr_data->frameInfo.nNoiseEnvelopes;
7972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Decode first noise envelope */
7992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (h_sbr_data->domain_vec_noise[0] == 0) {
8012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_SGL noiseLevel = h_sbr_data->sbrNoiseFloorLevel[0];
8022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i = 1; i < nNfb; i++) {
8032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      noiseLevel += h_sbr_data->sbrNoiseFloorLevel[i];
8042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      h_sbr_data->sbrNoiseFloorLevel[i] = noiseLevel;
8052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
8072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  else {
8082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i = 0; i < nNfb; i++) {
8092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      h_sbr_data->sbrNoiseFloorLevel[i] += h_prev_data->prevNoiseLevel[i];
8102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
8122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* If present, decode the second noise envelope
8142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project     Note:  nNoiseFloorEnvelopes can only be 1 or 2 */
8152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (nNoiseFloorEnvelopes > 1) {
8172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (h_sbr_data->domain_vec_noise[1] == 0) {
8182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      FIXP_SGL noiseLevel = h_sbr_data->sbrNoiseFloorLevel[nNfb];
8192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      for (i = nNfb + 1; i < 2*nNfb; i++) {
8202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        noiseLevel += h_sbr_data->sbrNoiseFloorLevel[i];
8212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_sbr_data->sbrNoiseFloorLevel[i] = noiseLevel;
8222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
8232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    else {
8252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      for (i = 0; i < nNfb; i++) {
8262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        h_sbr_data->sbrNoiseFloorLevel[i + nNfb] += h_sbr_data->sbrNoiseFloorLevel[i];
8272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
8282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
8302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  limitNoiseLevels(hHeaderData, h_sbr_data);
8322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Update prevNoiseLevel with the last noise envelope */
8342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i = 0; i < nNfb; i++)
8352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    h_prev_data->prevNoiseLevel[i] = h_sbr_data->sbrNoiseFloorLevel[i + nNfb*(nNoiseFloorEnvelopes-1)];
8362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Requantize the noise floor levels in COUPLING_OFF-mode */
8392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (!h_sbr_data->coupling) {
8402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    int nf_e;
8412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i = 0; i < nNoiseFloorEnvelopes*nNfb; i++) {
8432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      nf_e = 6 - (LONG)h_sbr_data->sbrNoiseFloorLevel[i] + 1 + NOISE_EXP_OFFSET;
8442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* +1 to compensate for a mantissa of 0.5 instead of 1.0 */
8452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      h_sbr_data->sbrNoiseFloorLevel[i] =
8472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        (FIXP_SGL)( ((LONG)FL2FXCONST_SGL(0.5f)) +  /* mantissa */
8482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                  (nf_e & MASK_E) ); /* exponent */
8492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
8522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
853