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/*****************************  MPEG-4 AAC Decoder  **************************
852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project   Author(s):   Josef Hoepfl
872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project   Description: perceptual noise substitution tool
882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project******************************************************************************/
902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "aacdec_pns.h"
922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "aac_ram.h"
952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "aac_rom.h"
962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "channelinfo.h"
972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "block.h"
982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "FDK_bitstream.h"
992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "genericStds.h"
1012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define NOISE_OFFSET 90           /* cf. ISO 14496-3 p. 175 */
1042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
1062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief Reset InterChannel and PNS data
1072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The function resets the InterChannel and PNS data
1092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
1102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid CPns_ResetData(
1112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    CPnsData *pPnsData,
1122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    CPnsInterChannelData *pPnsInterChannelData
1132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    )
1142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Assign pointer always, since pPnsData is not persistent data */
1162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPnsData->pPnsInterChannelData = pPnsInterChannelData;
1172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPnsData->PnsActive = 0;
1182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPnsData->CurrentEnergy = 0;
1192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKmemclear(pPnsData->pnsUsed,(8*16)*sizeof(UCHAR));
1212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKmemclear(pPnsInterChannelData->correlated,(8*16)*sizeof(UCHAR));
1222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
1252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief Initialize PNS data
1262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The function initializes the PNS data
1282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
1292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid CPns_InitPns(
1302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    CPnsData *pPnsData,
1312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    CPnsInterChannelData *pPnsInterChannelData,
1322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT* currentSeed, INT* randomSeed)
1332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* save pointer to inter channel data */
1352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPnsData->pPnsInterChannelData = pPnsInterChannelData;
1362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* use pointer because seed has to be
1382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project     same, left and right channel ! */
1392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPnsData->currentSeed = currentSeed;
1402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPnsData->randomSeed  = randomSeed;
1412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
1442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief Indicates if PNS is used
1452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The function returns a value indicating whether PNS is used or not
1472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  acordding to the noise energy
1482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \return  PNS used
1502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
1512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint CPns_IsPnsUsed (const CPnsData *pPnsData,
1522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    const int group,
1532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    const int band)
1542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  unsigned pns_band = group*16+band;
1562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return pPnsData->pnsUsed[pns_band] & (UCHAR)1;
1582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
1612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief Set correlation
1622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The function activates the noise correlation between the channel pair
1642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
1652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid CPns_SetCorrelation(CPnsData *pPnsData,
1662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         const int group,
1672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         const int band,
1682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         const int outofphase)
1692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData;
1712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  unsigned pns_band = group*16+band;
1722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pInterChannelData->correlated[pns_band] = (outofphase) ? 3 : 1;
1742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
1772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief Indicates if correlation is used
1782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The function indicates if the noise correlation between the channel pair
1802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  is activated
1812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \return  PNS is correlated
1832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
1842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic
1852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint CPns_IsCorrelated(const CPnsData *pPnsData,
1862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      const int group,
1872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      const int band)
1882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData;
1902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  unsigned pns_band = group*16+band;
1912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return (pInterChannelData->correlated[pns_band] & 0x01) ? 1 : 0;
1932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
1962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief Indicates if correlated out of phase mode is used.
1972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The function indicates if the noise correlation between the channel pair
1992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  is activated in out-of-phase mode.
2002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \return  PNS is out-of-phase
2022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
2032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic
2042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint CPns_IsOutOfPhase(const CPnsData *pPnsData,
2052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      const int group,
2062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      const int band)
2072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
2082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData;
2092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  unsigned pns_band = group*16+band;
2102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return (pInterChannelData->correlated[pns_band] & 0x02) ? 1 : 0;
2122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
2132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
2152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief Read PNS information
2162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The function reads the PNS information from the bitstream
2182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
2192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid CPns_Read (CPnsData *pPnsData,
2202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                HANDLE_FDK_BITSTREAM bs,
2212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                const CodeBookDescription *hcb,
2222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                SHORT *pScaleFactor,
2232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                UCHAR global_gain,
2242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                int band,
2252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                int group /* = 0 */)
2262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
2272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int delta ;
2282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  UINT pns_band = group*16+band;
2292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (pPnsData->PnsActive) {
2312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Next PNS band case */
2322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    delta = CBlock_DecodeHuffmanWord (bs, hcb) - 60;
2332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } else {
2342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* First PNS band case */
2352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    int noiseStartValue = FDKreadBits(bs,9);
2362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    delta = noiseStartValue - 256 ;
2382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPnsData->PnsActive = 1;
2392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPnsData->CurrentEnergy = global_gain - NOISE_OFFSET;
2402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPnsData->CurrentEnergy += delta ;
2432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pScaleFactor[pns_band] = pPnsData->CurrentEnergy;
2442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPnsData->pnsUsed[pns_band] = 1;
2462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
2472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/**
2502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief Generate a vector of noise of given length. The noise values are
2512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project *        scaled in order to yield a noise energy of 1.0
2522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \param spec pointer to were the noise values will be written to.
2532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \param size amount of noise values to be generated.
2542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \param pRandomState pointer to the state of the random generator being used.
2552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \return exponent of generated noise vector.
2562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
2572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic int GenerateRandomVector (FIXP_DBL *RESTRICT spec,
2582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                  int size,
2592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                  int *pRandomState)
2602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
2612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i, invNrg_e = 0, nrg_e = 0;
2622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_DBL invNrg_m, nrg_m = FL2FXCONST_DBL(0.0f) ;
2632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_DBL *RESTRICT ptr = spec;
2642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int randomState = *pRandomState;
2652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define GEN_NOISE_NRG_SCALE 7
2672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Generate noise and calculate energy. */
2692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i<size; i++)
2702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
2712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    randomState = (1664525L * randomState) + 1013904223L; // Numerical Recipes
2722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    nrg_m = fPow2AddDiv2(nrg_m, (FIXP_DBL)randomState>>GEN_NOISE_NRG_SCALE);
2732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *ptr++ = (FIXP_DBL)randomState;
2742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  nrg_e = GEN_NOISE_NRG_SCALE*2 + 1;
2762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* weight noise with = 1 / sqrt_nrg; */
2782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  invNrg_m = invSqrtNorm2(nrg_m<<1, &invNrg_e);
2792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  invNrg_e += -((nrg_e-1)>>1);
2802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=size; i--; )
2822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
2832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    spec[i] = fMult(spec[i], invNrg_m);
2842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Store random state */
2872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  *pRandomState = randomState;
2882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return invNrg_e;
2902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
2912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic void ScaleBand (FIXP_DBL *RESTRICT spec, int size, int scaleFactor, int specScale, int noise_e, int out_of_phase)
2932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
2942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i, shift, sfExponent;
2952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FIXP_DBL sfMatissa;
2962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Get gain from scale factor value = 2^(scaleFactor * 0.25) */
2982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  sfMatissa = MantissaTable[scaleFactor & 0x03][0];
2992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* sfExponent = (scaleFactor >> 2) + ExponentTable[scaleFactor & 0x03][0]; */
3002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Note:  ExponentTable[scaleFactor & 0x03][0] is always 1. */
3012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  sfExponent = (scaleFactor >> 2) + 1;
3022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (out_of_phase != 0) {
3042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sfMatissa = -sfMatissa;
3052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
3062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* +1 because of fMultDiv2 below. */
3082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  shift = sfExponent - specScale + 1 + noise_e;
3092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Apply gain to noise values */
3112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (shift>=0) {
3122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    shift = fixMin( shift, DFRACT_BITS-1 );
3132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i = size ; i-- != 0; ) {
3142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      spec [i] = fMultDiv2 (spec [i], sfMatissa) << shift;
3152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
3162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } else {
3172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    shift = fixMin( -shift, DFRACT_BITS-1 );
3182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i = size ; i-- != 0; ) {
3192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      spec [i] = fMultDiv2 (spec [i], sfMatissa) >> shift;
3202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
3212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
3222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
3232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*!
3262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  \brief Apply PNS
3272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  The function applies PNS (i.e. it generates noise) on the bands
3292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  flagged as noisy bands
3302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*/
3322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid CPns_Apply (const CPnsData *pPnsData,
3332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                 const CIcsInfo *pIcsInfo,
3342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                 SPECTRAL_PTR pSpectrum,
3352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                 const SHORT    *pSpecScale,
3362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                 const SHORT    *pScaleFactor,
3372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                 const SamplingRateInfo *pSamplingRateInfo,
3382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                 const INT granuleLength,
3392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                 const int channel)
3402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
3412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (pPnsData->PnsActive) {
3422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    const short *BandOffsets = GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo);
3432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    int ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(pIcsInfo);
3452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (int window = 0, group = 0; group < GetWindowGroups(pIcsInfo); group++) {
3472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      for (int groupwin = 0; groupwin < GetWindowGroupLength(pIcsInfo, group); groupwin++, window++) {
3482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FIXP_DBL *spectrum = SPEC(pSpectrum, window, granuleLength);
3492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for (int band = 0 ; band < ScaleFactorBandsTransmitted; band++) {
3512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          if (CPns_IsPnsUsed (pPnsData, group, band)) {
3522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            UINT pns_band = group*16+band;
3532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            int bandWidth = BandOffsets [band + 1] - BandOffsets [band] ;
3552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            int noise_e;
3562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDK_ASSERT(bandWidth >= 0);
3582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if (channel > 0 && CPns_IsCorrelated(pPnsData, group, band))
3602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            {
3612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              noise_e = GenerateRandomVector (spectrum + BandOffsets [band], bandWidth,
3622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    &pPnsData->randomSeed [pns_band]) ;
3632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
3642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            else
3652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            {
3662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              pPnsData->randomSeed [pns_band] = *pPnsData->currentSeed ;
3672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              noise_e = GenerateRandomVector (spectrum + BandOffsets [band], bandWidth,
3692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    pPnsData->currentSeed) ;
3702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
3712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            int outOfPhase  = CPns_IsOutOfPhase (pPnsData, group, band);
3732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            ScaleBand (spectrum + BandOffsets [band], bandWidth,
3752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       pScaleFactor[pns_band],
3762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       pSpecScale[window], noise_e, outOfPhase) ;
3772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
3782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
3792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
3802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
3812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
3822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
383