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
52228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project� Copyright  1995 - 2012 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 Audio Encoder **************************
852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project   Initial author:       M.Werner
872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project   contents/description: Psychoaccoustic major function block
882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project******************************************************************************/
902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "psy_const.h"
922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "block_switch.h"
942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "transform.h"
952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "spreading.h"
962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "pre_echo_control.h"
972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "band_nrg.h"
982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "psy_configuration.h"
992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "psy_data.h"
1002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "ms_stereo.h"
1012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "interface.h"
1022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "psy_main.h"
1032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "grp_data.h"
1042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "tns_func.h"
1052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "pns_func.h"
1062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "tonality.h"
1072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "aacEnc_ram.h"
1082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "intensity.h"
1092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* blending to reduce gibbs artifacts */
1132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#define FADE_OUT_LEN 6
1142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic const FIXP_DBL fadeOutFactor[FADE_OUT_LEN] = {1840644096, 1533870080, 1227096064, 920322048, 613548032, 306774016};
1152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* forward definitions */
1172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic inline int isLowDelay( AUDIO_OBJECT_TYPE aot )
1202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return (aot==AOT_ER_AAC_LD || aot==AOT_ER_AAC_ELD);
1222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************************************************************
1252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    functionname: FDKaacEnc_PsyNew
1272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    description:  allocates memory for psychoacoustic
1282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    returns:      an error code
1292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    input:        pointer to a psych handle
1302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*****************************************************************************/
1322228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL  **phpsy,
1332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                   const INT       nElements,
1342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                   const INT       nChannels
1352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                  ,UCHAR          *dynamic_RAM
1362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                  )
1372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    AAC_ENCODER_ERROR ErrorStatus;
1392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    PSY_INTERNAL *hPsy;
1402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT i;
1412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    hPsy = GetRam_aacEnc_PsyInternal();
1432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *phpsy = hPsy;
1442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (hPsy == NULL) {
1452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      ErrorStatus = AAC_ENC_NO_MEMORY;
1462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      goto bail;
1472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
1482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i=0; i<nElements; i++) {
1502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* PSY_ELEMENT */
1512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        hPsy->psyElement[i] = GetRam_aacEnc_PsyElement(i);
1522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (hPsy->psyElement[i] == NULL) {
1532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          ErrorStatus = AAC_ENC_NO_MEMORY;
1542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          goto bail;
1552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
1562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
1572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i=0; i<nChannels; i++) {
1592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* PSY_STATIC */
1602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        hPsy->pStaticChannels[i] = GetRam_aacEnc_PsyStatic(i);
1612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (hPsy->pStaticChannels[i]==NULL) {
1622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          ErrorStatus = AAC_ENC_NO_MEMORY;
1632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          goto bail;
1642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
1652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* AUDIO INPUT BUFFER */
1662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        hPsy->pStaticChannels[i]->psyInputBuffer = GetRam_aacEnc_PsyInputBuffer(i);
1672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (hPsy->pStaticChannels[i]->psyInputBuffer==NULL) {
1682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          ErrorStatus = AAC_ENC_NO_MEMORY;
1692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          goto bail;
1702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
1712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
1722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* reusable psych memory */
1742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    hPsy->psyDynamic = GetRam_aacEnc_PsyDynamic(0, dynamic_RAM);
1752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return AAC_ENC_OK;
1772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectbail:
1792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project   FDKaacEnc_PsyClose(phpsy, NULL);
1802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project   return ErrorStatus;
1822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************************************************************
1852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    functionname: FDKaacEnc_PsyOutNew
1872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    description:  allocates memory for psyOut struc
1882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    returns:      an error code
1892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    input:        pointer to a psych handle
1902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*****************************************************************************/
1922228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT   **phpsyOut,
1932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                      const INT   nElements,
1942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                      const INT   nChannels,
1952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                      const INT   nSubFrames
1962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                     ,UCHAR      *dynamic_RAM
1972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                     )
1982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  AAC_ENCODER_ERROR ErrorStatus;
2002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int n, i;
2012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int elInc = 0, chInc = 0;
2022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (n=0; n<nSubFrames; n++) {
2042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    phpsyOut[n] = GetRam_aacEnc_PsyOut(n);
2052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (phpsyOut[n] == NULL) {
2072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      ErrorStatus = AAC_ENC_NO_MEMORY;
2082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      goto bail;
2092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
2102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i=0; i<nChannels; i++) {
2122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      phpsyOut[n]->pPsyOutChannels[i] = GetRam_aacEnc_PsyOutChannel(chInc++);
2132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
2142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i=0; i<nElements; i++) {
2162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      phpsyOut[n]->psyOutElement[i] = GetRam_aacEnc_PsyOutElements(elInc++);
2172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (phpsyOut[n]->psyOutElement[i] == NULL) {
2182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        ErrorStatus = AAC_ENC_NO_MEMORY;
2192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        goto bail;
2202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
2212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
2222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } /* nSubFrames */
2232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return AAC_ENC_OK;
2252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectbail:
2272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKaacEnc_PsyClose(NULL, phpsyOut);
2282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return ErrorStatus;
2292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
2302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2322228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAAC_ENCODER_ERROR FDKaacEnc_psyInitStates(PSY_INTERNAL    *hPsy,
2332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                          PSY_STATIC* psyStatic,
2342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                          AUDIO_OBJECT_TYPE audioObjectType)
2352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
2362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* init input buffer */
2372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKmemclear(psyStatic->psyInputBuffer, MAX_INPUT_BUFFER_SIZE*sizeof(INT_PCM));
2382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKaacEnc_InitBlockSwitching(&psyStatic->blockSwitchingControl,
2402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                isLowDelay(audioObjectType)
2412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                               );
2422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return AAC_ENC_OK;
2442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
2452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2472228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL    *hPsy,
2482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    PSY_OUT        **phpsyOut,
2492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    const INT        nSubFrames,
2502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    const INT        nMaxChannels,
2512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    const AUDIO_OBJECT_TYPE audioObjectType,
2522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    CHANNEL_MAPPING *cm)
2532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
2542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
2552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i, ch, n, chInc = 0, resetChannels = 3;
2562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ( (nMaxChannels>2) && (cm->nChannels==2) ) {
2582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    chInc = 1;
2592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FDKaacEnc_psyInitStates(hPsy, hPsy->pStaticChannels[0], audioObjectType);
2602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ( (nMaxChannels==2) ) {
2632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    resetChannels = 0;
2642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i<cm->nElements; i++) {
2672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (ch=0; ch<cm->elInfo[i].nChannelsInEl; ch++) {
2682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (cm->elInfo[i].elType!=ID_LFE) {
2692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        hPsy->psyElement[i]->psyStatic[ch] = hPsy->pStaticChannels[chInc];
2702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (chInc>=resetChannels) {
2712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch], audioObjectType);
2722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
2732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        hPsy->psyElement[i]->psyStatic[ch]->isLFE = 0;
2742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
2752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      else {
2762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        hPsy->psyElement[i]->psyStatic[ch] = hPsy->pStaticChannels[nMaxChannels-1];
2772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        hPsy->psyElement[i]->psyStatic[ch]->isLFE = 1;
2782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
2792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      chInc++;
2802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
2812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (n=0; n<nSubFrames; n++) {
2842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    chInc = 0;
2852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (i=0; i<cm->nElements; i++) {
2862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      for (ch=0; ch<cm->elInfo[i].nChannelsInEl; ch++) {
2872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        phpsyOut[n]->psyOutElement[i]->psyOutChannel[ch] = phpsyOut[n]->pPsyOutChannels[chInc++];
2882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
2892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
2902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return ErrorStatus;
2932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
2942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************************************************************
2972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    functionname: FDKaacEnc_psyMainInit
2992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    description:  initializes psychoacoustic
3002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    returns:      an error code
3012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*****************************************************************************/
3032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3042228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAAC_ENCODER_ERROR FDKaacEnc_psyMainInit(PSY_INTERNAL *hPsy,
3052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        AUDIO_OBJECT_TYPE audioObjectType,
3062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        CHANNEL_MAPPING *cm,
3072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        INT sampleRate,
3082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        INT granuleLength,
3092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        INT bitRate,
3102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        INT tnsMask,
3112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        INT bandwidth,
3122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        INT usePns,
3132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        INT useIS,
3142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        UINT syntaxFlags,
3152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                        ULONG initFlags)
3162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
3172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  AAC_ENCODER_ERROR ErrorStatus;
3182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i, ch;
3192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int channelsEff = cm->nChannelsEff;
3202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int tnsChannels = 0;
3212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FB_TYPE filterBank;
3222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  switch(FDKaacEnc_GetMonoStereoMode(cm->encMode)) {
3252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* ... and map to tnsChannels */
3262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case EL_MODE_MONO:   tnsChannels = 1; break;
3272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case EL_MODE_STEREO: tnsChannels = 2; break;
3282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    default:             tnsChannels = 0;
3292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
3302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  switch (audioObjectType)
3322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
3332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    default: filterBank = FB_LC;  break;
3342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_AAC_LD:  filterBank = FB_LD;  break;
3352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_AAC_ELD: filterBank = FB_ELD; break;
3362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
3372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  hPsy->granuleLength = granuleLength;
3392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  ErrorStatus = FDKaacEnc_InitPsyConfiguration(bitRate/channelsEff, sampleRate, bandwidth, LONG_WINDOW, hPsy->granuleLength, useIS, &(hPsy->psyConf[0]), filterBank);
3412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (ErrorStatus != AAC_ENC_OK)
3422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return ErrorStatus;
3432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  ErrorStatus = FDKaacEnc_InitTnsConfiguration(
3452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        (bitRate*tnsChannels)/channelsEff,
3462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        sampleRate,
3472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        tnsChannels,
3482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        LONG_WINDOW,
3492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        hPsy->granuleLength,
3502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        (syntaxFlags&AC_SBR_PRESENT)?1:0,
3512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project       &(hPsy->psyConf[0].tnsConf),
3522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project       &hPsy->psyConf[0],
3532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        (INT)(tnsMask&2),
3542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        (INT)(tnsMask&8) );
3552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (ErrorStatus != AAC_ENC_OK)
3572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return ErrorStatus;
3582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (granuleLength > 512) {
3602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    ErrorStatus = FDKaacEnc_InitPsyConfiguration(bitRate/channelsEff, sampleRate, bandwidth, SHORT_WINDOW, hPsy->granuleLength, useIS, &hPsy->psyConf[1], filterBank);
3612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (ErrorStatus != AAC_ENC_OK)
3622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      return ErrorStatus;
3632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    ErrorStatus = FDKaacEnc_InitTnsConfiguration(
3652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            (bitRate*tnsChannels)/channelsEff,
3662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            sampleRate,
3672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            tnsChannels,
3682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            SHORT_WINDOW,
3692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            hPsy->granuleLength,
3702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            (syntaxFlags&AC_SBR_PRESENT)?1:0,
3712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project           &hPsy->psyConf[1].tnsConf,
3722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project           &hPsy->psyConf[1],
3732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            (INT)(tnsMask&1),
3742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            (INT)(tnsMask&4) );
3752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (ErrorStatus != AAC_ENC_OK)
3772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return ErrorStatus;
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  for (i=0; i<cm->nElements; i++) {
3832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (ch=0; ch<cm->elInfo[i].nChannelsInEl; ch++) {
3842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (initFlags) {
3852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* reset states */
3862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch], audioObjectType);
3872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
3882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      FDKaacEnc_InitPreEchoControl(hPsy->psyElement[i]->psyStatic[ch]->sfbThresholdnm1,
3902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                  &hPsy->psyElement[i]->psyStatic[ch]->calcPreEcho,
3912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                   hPsy->psyConf[0].sfbCnt,
3922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                   hPsy->psyConf[0].sfbPcmQuantThreshold,
3932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                  &hPsy->psyElement[i]->psyStatic[ch]->mdctScalenm1);
3942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
3952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
3962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
3972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  ErrorStatus = FDKaacEnc_InitPnsConfiguration(&hPsy->psyConf[0].pnsConf,
3982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               bitRate/channelsEff,
3992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               sampleRate,
4002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               usePns,
4012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               hPsy->psyConf[0].sfbCnt,
4022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               hPsy->psyConf[0].sfbOffset,
4032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               cm->elInfo[0].nChannelsInEl,
4042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               (hPsy->psyConf[0].filterbank == FB_LC));
4052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (ErrorStatus != AAC_ENC_OK)
4062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return ErrorStatus;
4072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  ErrorStatus = FDKaacEnc_InitPnsConfiguration(&hPsy->psyConf[1].pnsConf,
4092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               bitRate/channelsEff,
4102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               sampleRate,
4112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               usePns,
4122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               hPsy->psyConf[1].sfbCnt,
4132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               hPsy->psyConf[1].sfbOffset,
4142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               cm->elInfo[1].nChannelsInEl,
4152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                               (hPsy->psyConf[1].filterbank == FB_LC));
4162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return ErrorStatus;
4172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
4182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic
4212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid FDKaacEnc_deinterleaveInputBuffer(INT_PCM *pOutputSamples,
4222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                       INT_PCM *pInputSamples,
4232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                       INT nSamples,
4242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                       INT nChannels)
4252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
4262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT k;
4272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* deinterlave input samples and write to output buffer */
4282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for (k=0; k<nSamples; k++) {
4292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        pOutputSamples[k] = pInputSamples[k*nChannels];
4302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
4312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
4322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************************************************************
4362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    functionname: FDKaacEnc_psyMain
4382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    description:  psychoacoustic
4392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    returns:      an error code
4402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        This function assumes that enough input data is in the modulo buffer.
4422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project*****************************************************************************/
4442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4452228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAAC_ENCODER_ERROR FDKaacEnc_psyMain(INT                 channels,
4462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    PSY_ELEMENT        *psyElement,
4472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    PSY_DYNAMIC        *psyDynamic,
4482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    PSY_CONFIGURATION  *psyConf,
4492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    PSY_OUT_ELEMENT    *RESTRICT psyOutElement,
4502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    INT_PCM             *pInput,
4512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    INT                 *chIdx,
4522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    INT                  totalChannels
4532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                   )
4542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
4552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT commonWindow = 1;
4562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT maxSfbPerGroup[(2)];
4572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT mdctSpectrum_e;
4582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT ch;   /* counts through channels          */
4592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT w;    /* counts through windows           */
4602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT sfb;  /* counts through scalefactor bands */
4612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT line; /* counts through lines             */
4622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    PSY_CONFIGURATION *RESTRICT hPsyConfLong  = &psyConf[0];
4642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    PSY_CONFIGURATION *RESTRICT hPsyConfShort = &psyConf[1];
4652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    PSY_OUT_CHANNEL  **RESTRICT psyOutChannel = psyOutElement->psyOutChannel;
4662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_SGL sfbTonality[(2)][MAX_SFB_LONG];
4672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    PSY_STATIC        **RESTRICT psyStatic = psyElement->psyStatic;
4692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    PSY_DATA           *RESTRICT psyData[(2)];
4712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    TNS_DATA           *RESTRICT tnsData[(2)];
4722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    PNS_DATA           *RESTRICT pnsData[(2)];
4732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT zeroSpec = TRUE; /* means all spectral lines are zero */
4752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT blockSwitchingOffset;
4772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    PSY_CONFIGURATION *RESTRICT hThisPsyConf[(2)];
4792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT windowLength[(2)];
4802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT nWindows[(2)];
4812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT wOffset;
4822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT       maxSfb[(2)];
4842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT      *pSfbMaxScaleSpec[(2)];
4852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL *pSfbEnergy[(2)];
4862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL *pSfbSpreadEnergy[(2)];
4872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL *pSfbEnergyLdData[(2)];
4882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL *pSfbEnergyMS[(2)];
4892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    FIXP_DBL *pSfbThreshold[(2)];
4902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    INT isShortWindow[(2)];
4922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (hPsyConfLong->filterbank == FB_LC) {
4952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      blockSwitchingOffset = psyConf->granuleLength + (9*psyConf->granuleLength/(2*TRANS_FAC));
4962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } else {
4972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      blockSwitchingOffset = psyConf->granuleLength;
4982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
4992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for(ch = 0; ch < channels; ch++)
5012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
5022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        psyData[ch] = &psyDynamic->psyData[ch];
5032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        tnsData[ch] = &psyDynamic->tnsData[ch];
5042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        pnsData[ch] = &psyDynamic->pnsData[ch];
5052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        psyData[ch]->mdctSpectrum = psyOutChannel[ch]->mdctSpectrum;
5072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* block switching */
5102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (hPsyConfLong->filterbank != FB_ELD)
5112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
5122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      int err;
5132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      for(ch = 0; ch < channels; ch++)
5152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      {
5162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          C_ALLOC_SCRATCH_START(timeSignal, INT_PCM, (1024));
5172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          psyStatic[ch]->blockSwitchingControl.timeSignal = timeSignal;
5182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          /* deinterleave input data and use for block switching */
5202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          FDKaacEnc_deinterleaveInputBuffer( psyStatic[ch]->blockSwitchingControl.timeSignal,
5212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                            &pInput[chIdx[ch]],
5222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                             psyConf->granuleLength,
5232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                             totalChannels);
5242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          FDKaacEnc_BlockSwitching (&psyStatic[ch]->blockSwitchingControl,
5272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                     psyConf->granuleLength
5282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    ,psyStatic[ch]->isLFE
5292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                   );
5302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* fill up internal input buffer, to 2xframelength samples */
5332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKmemcpy(psyStatic[ch]->psyInputBuffer+blockSwitchingOffset,
5342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      psyStatic[ch]->blockSwitchingControl.timeSignal,
5352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      (2*psyConf->granuleLength-blockSwitchingOffset)*sizeof(INT_PCM));
5362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            C_ALLOC_SCRATCH_END(timeSignal, INT_PCM, (1024));
5382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
5392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* synch left and right block type */
5412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      err = FDKaacEnc_SyncBlockSwitching(&psyStatic[0]->blockSwitchingControl,
5422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                         &psyStatic[1]->blockSwitchingControl,
5432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                          channels,
5442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                          commonWindow);
5452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (err) {
5472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          return AAC_ENC_UNSUPPORTED_AOT; /* mixed up LC and LD */
5482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
5492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    else {
5522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      for(ch = 0; ch < channels; ch++)
5532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      {
5542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* deinterleave input data and use for block switching */
5552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FDKaacEnc_deinterleaveInputBuffer( psyStatic[ch]->psyInputBuffer + blockSwitchingOffset,
5562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                          &pInput[chIdx[ch]],
5572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           psyConf->granuleLength,
5582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           totalChannels);
5592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
5602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for(ch = 0; ch < channels; ch++)
5632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      isShortWindow[ch]=(psyStatic[ch]->blockSwitchingControl.lastWindowSequence == SHORT_WINDOW);
5642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* set parameters according to window length */
5662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for(ch = 0; ch < channels; ch++)
5672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
5682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if(isShortWindow[ch]) {
5692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            hThisPsyConf[ch]       = hPsyConfShort;
5702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            windowLength[ch]       = psyConf->granuleLength/TRANS_FAC;
5712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            nWindows[ch]           = TRANS_FAC;
5722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            maxSfb[ch]             = MAX_SFB_SHORT;
5732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            pSfbMaxScaleSpec[ch]   = psyData[ch]->sfbMaxScaleSpec.Short[0];
5752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            pSfbEnergy[ch]         = psyData[ch]->sfbEnergy.Short[0];
5762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            pSfbSpreadEnergy[ch]   = psyData[ch]->sfbSpreadEnergy.Short[0];
5772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            pSfbEnergyLdData[ch]   = psyData[ch]->sfbEnergyLdData.Short[0];
5782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            pSfbEnergyMS[ch]       = psyData[ch]->sfbEnergyMS.Short[0];
5792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            pSfbThreshold[ch]      = psyData[ch]->sfbThreshold.Short[0];
5802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        } else
5822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        {
5832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            hThisPsyConf[ch]       = hPsyConfLong;
5842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            windowLength[ch]       = psyConf->granuleLength;
5852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            nWindows[ch]           = 1;
5862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            maxSfb[ch]             = MAX_GROUPED_SFB;
5872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            pSfbMaxScaleSpec[ch]   = psyData[ch]->sfbMaxScaleSpec.Long;
5892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            pSfbEnergy[ch]         = psyData[ch]->sfbEnergy.Long;
5902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            pSfbSpreadEnergy[ch]   = psyData[ch]->sfbSpreadEnergy.Long;
5912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            pSfbEnergyLdData[ch]   = psyData[ch]->sfbEnergyLdData.Long;
5922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            pSfbEnergyMS[ch]       = psyData[ch]->sfbEnergyMS.Long;
5932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            pSfbThreshold[ch]      = psyData[ch]->sfbThreshold.Long;
5942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
5952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Transform and get mdctScaling for all channels and windows. */
5982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for(ch = 0; ch < channels; ch++)
5992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
6002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* update number of active bands */
6012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (psyStatic[ch]->isLFE) {
6022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActiveLFE;
6032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLineLFE;
6042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        } else
6052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        {
6062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActive;
6072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLine;
6082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
6092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for(w = 0; w < nWindows[ch]; w++) {
6112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          wOffset = w*windowLength[ch];
6132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          FDKaacEnc_Transform_Real( psyStatic[ch]->psyInputBuffer + wOffset,
6152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    psyData[ch]->mdctSpectrum+wOffset,
6162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    psyStatic[ch]->blockSwitchingControl.lastWindowSequence,
6172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    psyStatic[ch]->blockSwitchingControl.windowShape,
6182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                   &psyStatic[ch]->blockSwitchingControl.lastWindowShape,
6192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    psyConf->granuleLength,
6202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                   &mdctSpectrum_e,
6212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                    hThisPsyConf[ch]->filterbank
6222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                   ,psyStatic[ch]->overlapAddBuffer
6232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                   );
6242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          /* Low pass / highest sfb */
6262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          FDKmemclear(&psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset],
6272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      (windowLength[ch]-psyData[ch]->lowpassLine)*sizeof(FIXP_DBL));
6282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          if (hPsyConfLong->filterbank != FB_LC) {
6302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* Do blending to reduce gibbs artifacts */
6312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for (int i=0; i<FADE_OUT_LEN; i++) {
6322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i] = fMult(psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i], fadeOutFactor[i]);
6332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
6342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
6352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          /* Check for zero spectrum. These loops will usually terminate very, very early. */
6382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          for(line=0; (line<psyData[ch]->lowpassLine) && (zeroSpec==TRUE); line++) {
6392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              if (psyData[ch]->mdctSpectrum[line+wOffset] != (FIXP_DBL)0) {
6402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                  zeroSpec = FALSE;
6412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                  break;
6422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              }
6432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
6442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        } /* w loop */
6462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        psyData[ch]->mdctScale = mdctSpectrum_e;
6482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* rotate internal time samples */
6502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FDKmemmove(psyStatic[ch]->psyInputBuffer,
6512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   psyStatic[ch]->psyInputBuffer+psyConf->granuleLength,
6522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   psyConf->granuleLength*sizeof(INT_PCM));
6532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* ... and get remaining samples from input buffer */
6562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FDKaacEnc_deinterleaveInputBuffer( psyStatic[ch]->psyInputBuffer+psyConf->granuleLength,
6572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                          &pInput[ (2*psyConf->granuleLength-blockSwitchingOffset)*totalChannels + chIdx[ch] ],
6582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           blockSwitchingOffset-psyConf->granuleLength,
6592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           totalChannels);
6602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } /* ch */
6622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Do some rescaling to get maximum possible accuracy for energies */
6642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if ( zeroSpec == FALSE) {
6652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* Calc possible spectrum leftshift for each sfb (1 means: 1 bit left shift is possible without overflow) */
6672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT minSpecShift = MAX_SHIFT_DBL;
6682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT nrgShift     = MAX_SHIFT_DBL;
6692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT finalShift   = MAX_SHIFT_DBL;
6702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FIXP_DBL currNrg = 0;
6712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FIXP_DBL maxNrg  = 0;
6722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for(ch = 0; ch < channels; ch++) {
6742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for(w = 0; w < nWindows[ch]; w++) {
6752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                wOffset = w*windowLength[ch];
6762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                FDKaacEnc_CalcSfbMaxScaleSpec(psyData[ch]->mdctSpectrum+wOffset,
6772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                              hThisPsyConf[ch]->sfbOffset,
6782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                              pSfbMaxScaleSpec[ch]+w*maxSfb[ch],
6792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                              psyData[ch]->sfbActive);
6802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                for (sfb = 0; sfb<psyData[ch]->sfbActive; sfb++)
6822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    minSpecShift = fixMin(minSpecShift, (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb]);
6832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
6842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
6862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* Calc possible energy leftshift for each sfb (1 means: 1 bit left shift is possible without overflow) */
6882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for(ch = 0; ch < channels; ch++) {
6892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for(w = 0; w < nWindows[ch]; w++) {
6902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                wOffset = w*windowLength[ch];
6912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                currNrg = FDKaacEnc_CheckBandEnergyOptim(psyData[ch]->mdctSpectrum+wOffset,
6922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                                        pSfbMaxScaleSpec[ch]+w*maxSfb[ch],
6932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                                        hThisPsyConf[ch]->sfbOffset,
6942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                                        psyData[ch]->sfbActive,
6952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                                        pSfbEnergy[ch]+w*maxSfb[ch],
6962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                                        pSfbEnergyLdData[ch]+w*maxSfb[ch],
6972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                                        minSpecShift-4);
6982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                maxNrg = fixMax(maxNrg, currNrg);
7002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
7012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
7022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if ( maxNrg != (FIXP_DBL)0 ) {
7042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            nrgShift = (CountLeadingBits(maxNrg)>>1) + (minSpecShift-4);
7052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
7062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* 2check: Hasn't this decision to be made for both channels? */
7082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* For short windows 1 additional bit headroom is necessary to prevent overflows when summing up energies in FDKaacEnc_groupShortData() */
7092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if(isShortWindow[0]) nrgShift--;
7102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* both spectrum and energies mustn't overflow */
7122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        finalShift = fixMin(minSpecShift, nrgShift);
7132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* do not shift more than 3 bits more to the left than signal without blockfloating point
7152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project         * would be to avoid overflow of scaled PCM quantization thresholds */
7162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (finalShift > psyData[0]->mdctScale + 3 )
7172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            finalShift = psyData[0]->mdctScale + 3;
7182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FDK_ASSERT(finalShift >= 0);    /* right shift is not allowed */
7202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* correct sfbEnergy and sfbEnergyLdData with new finalShift */
7222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FIXP_DBL ldShift = finalShift * FL2FXCONST_DBL(2.0/64);
7232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for(ch = 0; ch < channels; ch++) {
7242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for(w = 0; w < nWindows[ch]; w++) {
7252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                for(sfb=0; sfb<psyData[ch]->sfbActive; sfb++) {
7262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    INT scale = fixMax(0, (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb]-4);
7272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    scale     = fixMin((scale-finalShift)<<1, DFRACT_BITS-1);
7282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    if (scale >= 0) (pSfbEnergy[ch]+w*maxSfb[ch])[sfb] >>= (scale);
7292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    else            (pSfbEnergy[ch]+w*maxSfb[ch])[sfb] <<= (-scale);
7302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    (pSfbThreshold[ch]+w*maxSfb[ch])[sfb] = fMult((pSfbEnergy[ch]+w*maxSfb[ch])[sfb], C_RATIO);
7312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    (pSfbEnergyLdData[ch]+w*maxSfb[ch])[sfb] += ldShift;
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        if ( finalShift != 0 ) {
7372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for (ch = 0; ch < channels; ch++) {
7382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                for(w = 0; w < nWindows[ch]; w++) {
7392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    wOffset = w*windowLength[ch];
7402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    for(line=0; line<psyData[ch]->lowpassLine; line++) {
7412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        psyData[ch]->mdctSpectrum[line+wOffset] <<= finalShift;
7422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    }
7432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    /* update sfbMaxScaleSpec */
7442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    for (sfb = 0; sfb<psyData[ch]->sfbActive; sfb++)
7452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb] -= finalShift;
7462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                }
7472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                /* update mdctScale */
7482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                psyData[ch]->mdctScale -= finalShift;
7492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
7502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
7512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    } else {
7532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* all spectral lines are zero */
7542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for (ch = 0; ch < channels; ch++) {
7552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyData[ch]->mdctScale = 0;     /* otherwise mdctScale would be for example 7 and PCM quantization thresholds would be shifted
7562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                             * 14 bits to the right causing some of them to become 0 (which causes problems later) */
7572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* clear sfbMaxScaleSpec */
7582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for(w = 0; w < nWindows[ch]; w++) {
7592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                for (sfb = 0; sfb<psyData[ch]->sfbActive; sfb++) {
7602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb] = 0;
7612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    (pSfbEnergy[ch]+w*maxSfb[ch])[sfb]       = (FIXP_DBL)0;
7622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    (pSfbEnergyLdData[ch]+w*maxSfb[ch])[sfb] = FL2FXCONST_DBL(-1.0f);
7632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    (pSfbThreshold[ch]+w*maxSfb[ch])[sfb]    = (FIXP_DBL)0;
7642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                }
7652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
7662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
7672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
7682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Advance psychoacoustics: Tonality and TNS */
7702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (psyStatic[0]->isLFE) {
7712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive = 0;
7722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
7732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    else
7742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
7752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for(ch = 0; ch < channels; ch++) {
7772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if (!isShortWindow[ch]) {
7782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                /* tonality */
7792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                FDKaacEnc_CalculateFullTonality( psyData[ch]->mdctSpectrum,
7802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                       pSfbMaxScaleSpec[ch],
7812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                       pSfbEnergyLdData[ch],
7822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                       sfbTonality[ch],
7832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                       psyData[ch]->sfbActive,
7842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                       hThisPsyConf[ch]->sfbOffset,
7852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                       hThisPsyConf[ch]->pnsConf.usePns);
7862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
7872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
7882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (hPsyConfLong->tnsConf.tnsActive || hPsyConfShort->tnsConf.tnsActive) {
7902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            INT tnsActive[TRANS_FAC];
7912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            INT nrgScaling[2] = {0,0};
7922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            INT tnsSpecShift = 0;
7932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for(ch = 0; ch < channels; ch++) {
7952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                for(w = 0; w < nWindows[ch]; w++) {
7962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
7972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    wOffset = w*windowLength[ch];
7982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    /* TNS */
7992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    FDKaacEnc_TnsDetect(
8002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                tnsData[ch],
8012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                &hThisPsyConf[ch]->tnsConf,
8022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                &psyOutChannel[ch]->tnsInfo,
8032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                hThisPsyConf[ch]->sfbCnt,
8042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[ch]->mdctSpectrum+wOffset,
8052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                w,
8062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyStatic[ch]->blockSwitchingControl.lastWindowSequence
8072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                );
8082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                }
8092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
8102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if (channels == 2) {
8122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              FDKaacEnc_TnsSync(
8132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      tnsData[1],
8142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      tnsData[0],
8152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      &psyOutChannel[1]->tnsInfo,
8162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      &psyOutChannel[0]->tnsInfo,
8172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      psyStatic[1]->blockSwitchingControl.lastWindowSequence,
8192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      psyStatic[0]->blockSwitchingControl.lastWindowSequence,
8202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                      &hThisPsyConf[1]->tnsConf);
8212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
8222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDK_ASSERT(commonWindow=1); /* all checks for TNS do only work for common windows (which is always set)*/
8242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for(w = 0; w < nWindows[0]; w++)
8252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            {
8262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                if (isShortWindow[0])
8272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    tnsActive[w] = tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive ||
8282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    ((channels == 2) ? tnsData[1]->dataRaw.Short.subBlockInfo[w].tnsActive : 0);
8292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                else
8302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    tnsActive[w] = tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive ||
8312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    ((channels == 2) ? tnsData[1]->dataRaw.Long.subBlockInfo.tnsActive : 0);
8322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
8332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for(ch = 0; ch < channels; ch++) {
8352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                if (tnsActive[0] && !isShortWindow[ch]) {
8362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    /* Scale down spectrum if tns is active in one of the two channels with same lastWindowSequence */
8372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    /* first part of threshold calculation; it's not necessary to update sfbMaxScaleSpec */
8382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    INT shift = 1;
8392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    for(sfb=0; sfb<hThisPsyConf[ch]->lowpassLine; sfb++) {
8402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        psyData[ch]->mdctSpectrum[sfb] = psyData[ch]->mdctSpectrum[sfb] >> shift;
8412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    }
8422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    /* update thresholds */
8442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    for (sfb=0; sfb<psyData[ch]->sfbActive; sfb++) {
8452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        pSfbThreshold[ch][sfb] >>= (2*shift);
8462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    }
8472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    psyData[ch]->mdctScale += shift; /* update mdctScale */
8492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    /* calc sfbEnergies after tnsEncode again ! */
8512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                }
8532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
8542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for(ch = 0; ch < channels; ch++) {
8562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              for(w = 0; w < nWindows[ch]; w++)
8572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                {
8582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    wOffset = w*windowLength[ch];
8592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    FDKaacEnc_TnsEncode(
8602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                &psyOutChannel[ch]->tnsInfo,
8612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                tnsData[ch],
8622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                hThisPsyConf[ch]->sfbCnt,
8632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                &hThisPsyConf[ch]->tnsConf,
8642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                hThisPsyConf[ch]->sfbOffset[psyData[ch]->sfbActive],/*hThisPsyConf[ch]->lowpassLine*/ /* filter stops before that line ! */
8652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[ch]->mdctSpectrum+wOffset,
8662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                w,
8672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyStatic[ch]->blockSwitchingControl.lastWindowSequence);
8682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    if(tnsActive[w]) {
8702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            /* Calc sfb-bandwise mdct-energies for left and right channel again, */
8712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            /* if tns active in current channel or in one channel with same lastWindowSequence left and right */
8722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            FDKaacEnc_CalcSfbMaxScaleSpec(psyData[ch]->mdctSpectrum+wOffset,
8732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                                hThisPsyConf[ch]->sfbOffset,
8742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                                pSfbMaxScaleSpec[ch]+w*maxSfb[ch],
8752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                                psyData[ch]->sfbActive);
8762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    }
8772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                }
8782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
8792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for(ch = 0; ch < channels; ch++) {
8812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              for(w = 0; w < nWindows[ch]; w++) {
8822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                if (tnsActive[w]) {
8842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                  if (isShortWindow[ch]) {
8862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    FDKaacEnc_CalcBandEnergyOptimShort(psyData[ch]->mdctSpectrum+w*windowLength[ch],
8872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                             pSfbMaxScaleSpec[ch]+w*maxSfb[ch],
8882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                             hThisPsyConf[ch]->sfbOffset,
8892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                             psyData[ch]->sfbActive,
8902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                             pSfbEnergy[ch]+w*maxSfb[ch]);
8912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                  }
8922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                  else {
8932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    nrgScaling[ch] =        /* with tns, energy calculation can overflow; -> scaling */
8942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    FDKaacEnc_CalcBandEnergyOptimLong(psyData[ch]->mdctSpectrum,
8952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           pSfbMaxScaleSpec[ch],
8962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           hThisPsyConf[ch]->sfbOffset,
8972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           psyData[ch]->sfbActive,
8982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           pSfbEnergy[ch],
8992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           pSfbEnergyLdData[ch]);
9002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    tnsSpecShift = fixMax(tnsSpecShift, nrgScaling[ch]);       /* nrgScaling is set only if nrg would have an overflow */
9012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                  }
9022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                } /* if tnsActive */
9032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              }
9042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            } /* end channel loop */
9052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* adapt scaling to prevent nrg overflow, only for long blocks */
9072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for(ch = 0; ch < channels; ch++) {
9082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              if ( (tnsSpecShift!=0) && !isShortWindow[ch] ) {
9092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                /* scale down spectrum, nrg's and thresholds, if there was an overflow in sfbNrg calculation after tns */
9102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                for(line=0; line<hThisPsyConf[ch]->lowpassLine; line++) {
9112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                  psyData[ch]->mdctSpectrum[line] >>= tnsSpecShift;
9122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                }
9132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                INT scale = (tnsSpecShift-nrgScaling[ch])<<1;
9142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                for(sfb=0; sfb<psyData[ch]->sfbActive; sfb++) {
9152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                  pSfbEnergyLdData[ch][sfb]   -= scale*FL2FXCONST_DBL(1.0/LD_DATA_SCALING);
9162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                  pSfbEnergy[ch][sfb]        >>= scale;
9172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                  pSfbThreshold[ch][sfb]     >>= (tnsSpecShift<<1);
9182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                }
9192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                psyData[ch]->mdctScale += tnsSpecShift;  /* update mdctScale; not necessary to update sfbMaxScaleSpec */
9202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              }
9222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            } /* end channel loop */
9232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        } /* TNS active */
9252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }  /* !isLFE */
9262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Advance thresholds */
9332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for(ch = 0; ch < channels; ch++) {
9342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT headroom;
9352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FIXP_DBL clipEnergy;
9372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT energyShift  = psyData[ch]->mdctScale*2 ;
9382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT clipNrgShift = energyShift - THR_SHIFTBITS ;
9392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if(isShortWindow[ch])
9412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            headroom = 6;
9422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        else
9432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            headroom = 0;
9442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (clipNrgShift >= 0)
9462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            clipEnergy = hThisPsyConf[ch]->clipEnergy >>  clipNrgShift ;
9472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        else if (clipNrgShift>=-headroom)
9482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            clipEnergy = hThisPsyConf[ch]->clipEnergy << -clipNrgShift ;
9492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        else
9502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            clipEnergy = (FIXP_DBL)MAXVAL_DBL ;
9512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for(w = 0; w < nWindows[ch]; w++)
9532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        {
9542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            INT i;
9552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* limit threshold to avoid clipping */
9562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for (i=0; i<psyData[ch]->sfbActive; i++) {
9572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                *(pSfbThreshold[ch]+w*maxSfb[ch]+i) = fixMin(*(pSfbThreshold[ch]+w*maxSfb[ch]+i), clipEnergy);
9582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
9592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* spreading */
9612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive,
9622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            hThisPsyConf[ch]->sfbMaskLowFactor,
9632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            hThisPsyConf[ch]->sfbMaskHighFactor,
9642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            pSfbThreshold[ch]+w*maxSfb[ch]);
9652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* PCM quantization threshold */
9682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            energyShift += PCM_QUANT_THR_SCALE;
9692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if (energyShift>=0) {
9702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project               energyShift = fixMin(DFRACT_BITS-1,energyShift);
9712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project               for (i=0; i<psyData[ch]->sfbActive;i++) {
9722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   *(pSfbThreshold[ch]+w*maxSfb[ch]+i) = fixMax(*(pSfbThreshold[ch]+w*maxSfb[ch]+i) >> THR_SHIFTBITS,
9732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                                          (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] >> energyShift));
9742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project               }
9752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            } else {
9762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project               energyShift = fixMin(DFRACT_BITS-1,-energyShift);
9772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project               for (i=0; i<psyData[ch]->sfbActive;i++) {
9782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                   *(pSfbThreshold[ch]+w*maxSfb[ch]+i) = fixMax(*(pSfbThreshold[ch]+w*maxSfb[ch]+i) >> THR_SHIFTBITS,
9792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                                          (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] << energyShift));
9802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project               }
9812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
9822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if (!psyStatic[ch]->isLFE)
9842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            {
9852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                /* preecho control */
9862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                if(psyStatic[ch]->blockSwitchingControl.lastWindowSequence == STOP_WINDOW) {
9872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    /* prevent FDKaacEnc_PreEchoControl from comparing stop
9882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       thresholds with short thresholds */
9892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    for (i=0; i<psyData[ch]->sfbActive;i++) {
9902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL;
9912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    }
9922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    psyStatic[ch]->mdctScalenm1 = 0;
9942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    psyStatic[ch]->calcPreEcho  = 0;
9952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                }
9962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                FDKaacEnc_PreEchoControl( psyStatic[ch]->sfbThresholdnm1,
9982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyStatic[ch]->calcPreEcho,
9992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[ch]->sfbActive,
10002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                hThisPsyConf[ch]->maxAllowedIncreaseFactor,
10012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                hThisPsyConf[ch]->minRemainingThresholdFactor,
10022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                pSfbThreshold[ch]+w*maxSfb[ch],
10032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[ch]->mdctScale,
10042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                &psyStatic[ch]->mdctScalenm1);
10052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                psyStatic[ch]->calcPreEcho = 1;
10072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                if(psyStatic[ch]->blockSwitchingControl.lastWindowSequence == START_WINDOW)
10092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                {
10102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    /* prevent FDKaacEnc_PreEchoControl in next frame to compare start
10112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       thresholds with short thresholds */
10122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    for (i=0; i<psyData[ch]->sfbActive;i++) {
10132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL;
10142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    }
10152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    psyStatic[ch]->mdctScalenm1 = 0;
10172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    psyStatic[ch]->calcPreEcho  = 0;
10182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                }
10192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
10212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* spread energy to avoid hole detection */
10232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKmemcpy(pSfbSpreadEnergy[ch]+w*maxSfb[ch], pSfbEnergy[ch]+w*maxSfb[ch], psyData[ch]->sfbActive*sizeof(FIXP_DBL));
10242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive,
10262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         hThisPsyConf[ch]->sfbMaskLowFactorSprEn,
10272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         hThisPsyConf[ch]->sfbMaskHighFactorSprEn,
10282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         pSfbSpreadEnergy[ch]+w*maxSfb[ch]);
10292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
10302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
10312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Calc bandwise energies for mid and side channel. Do it only if 2 channels exist */
10332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (channels==2) {
10342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for(w = 0; w < nWindows[1]; w++) {
10352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            wOffset = w*windowLength[1];
10362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKaacEnc_CalcBandNrgMSOpt(psyData[0]->mdctSpectrum+wOffset,
10372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             psyData[1]->mdctSpectrum+wOffset,
10382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             pSfbMaxScaleSpec[0]+w*maxSfb[0],
10392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             pSfbMaxScaleSpec[1]+w*maxSfb[1],
10402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             hThisPsyConf[1]->sfbOffset,
10412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             psyData[0]->sfbActive,
10422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             pSfbEnergyMS[0]+w*maxSfb[0],
10432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             pSfbEnergyMS[1]+w*maxSfb[1],
10442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             (psyStatic[1]->blockSwitchingControl.lastWindowSequence != SHORT_WINDOW),
10452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             psyData[0]->sfbEnergyMSLdData,
10462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                             psyData[1]->sfbEnergyMSLdData);
10472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
10482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
10492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* group short data (maxSfb[ch] for short blocks is determined here) */
10512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for(ch=0;ch<channels;ch++)
10522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
10532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT noSfb, i;
10542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if(isShortWindow[ch])
10552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        {
10562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            int sfbGrp;
10572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            noSfb = psyStatic[ch]->blockSwitchingControl.noOfGroups * hPsyConfShort->sfbCnt;
10582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* At this point, energies and thresholds are copied/regrouped from the ".Short" to the ".Long" arrays */
10592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKaacEnc_groupShortData( psyData[ch]->mdctSpectrum,
10602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            &psyData[ch]->sfbThreshold,
10612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            &psyData[ch]->sfbEnergy,
10622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            &psyData[ch]->sfbEnergyMS,
10632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            &psyData[ch]->sfbSpreadEnergy,
10642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            hPsyConfShort->sfbCnt,
10652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            psyData[ch]->sfbActive,
10662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            hPsyConfShort->sfbOffset,
10672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            hPsyConfShort->sfbMinSnrLdData,
10682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            psyData[ch]->groupedSfbOffset,
10692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            &maxSfbPerGroup[ch],
10702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            psyOutChannel[ch]->sfbMinSnrLdData,
10712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            psyStatic[ch]->blockSwitchingControl.noOfGroups,
10722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            psyStatic[ch]->blockSwitchingControl.groupLen,
10732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                            psyConf[1].granuleLength);
10742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* calculate ldData arrays (short values are in .Long-arrays after FDKaacEnc_groupShortData) */
10772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) {
10782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              LdDataVector(&psyData[ch]->sfbEnergy.Long[sfbGrp], &psyOutChannel[ch]->sfbEnergyLdData[sfbGrp], psyData[ch]->sfbActive);
10792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
10802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/
10822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) {
10832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              LdDataVector(&psyData[ch]->sfbThreshold.Long[sfbGrp], &psyOutChannel[ch]->sfbThresholdLdData[sfbGrp], psyData[ch]->sfbActive);
10842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              for (sfb=0;sfb<psyData[ch]->sfbActive;sfb++) {
10852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                psyOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb] =
10862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                           fixMax(psyOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb], FL2FXCONST_DBL(-0.515625f));
10872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              }
10882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
10892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if ( channels==2 ) {
10912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) {
10922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                LdDataVector(&psyData[ch]->sfbEnergyMS.Long[sfbGrp], &psyData[ch]->sfbEnergyMSLdData[sfbGrp], psyData[ch]->sfbActive);
10932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              }
10942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
10952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKmemcpy(psyOutChannel[ch]->sfbOffsets, psyData[ch]->groupedSfbOffset, (MAX_GROUPED_SFB+1)*sizeof(INT));
10972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        } else {
10992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* maxSfb[ch] for long blocks */
11002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for (sfb = psyData[ch]->sfbActive-1; sfb >= 0; sfb--) {
11012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                for (line = hPsyConfLong->sfbOffset[sfb+1]-1; line >= hPsyConfLong->sfbOffset[sfb]; line--) {
11022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                    if (psyData[ch]->mdctSpectrum[line] != FL2FXCONST_SGL(0.0f)) break;
11032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                }
11042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                if (line > hPsyConfLong->sfbOffset[sfb]) break;
11052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
11062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            maxSfbPerGroup[ch] = sfb + 1;
11072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* ensure at least one section in ICS; workaround for existing decoder crc implementation */
11082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            maxSfbPerGroup[ch] = fixMax(fixMin(5,psyData[ch]->sfbActive),maxSfbPerGroup[ch]);
11092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* sfbNrgLdData is calculated in FDKaacEnc_advancePsychLong, copy in psyOut structure */
11112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKmemcpy(psyOutChannel[ch]->sfbEnergyLdData, psyData[ch]->sfbEnergyLdData.Long, psyData[ch]->sfbActive*sizeof(FIXP_DBL));
11122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKmemcpy(psyOutChannel[ch]->sfbOffsets, hPsyConfLong->sfbOffset, (MAX_GROUPED_SFB+1)*sizeof(INT));
11142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* sfbMinSnrLdData modified in adjust threshold, copy necessary */
11162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKmemcpy(psyOutChannel[ch]->sfbMinSnrLdData, hPsyConfLong->sfbMinSnrLdData, psyData[ch]->sfbActive*sizeof(FIXP_DBL));
11172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* sfbEnergyMSLdData ist already calculated in FDKaacEnc_CalcBandNrgMSOpt; only in long case */
11192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/
11212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            LdDataVector(psyData[ch]->sfbThreshold.Long, psyOutChannel[ch]->sfbThresholdLdData, psyData[ch]->sfbActive);
11222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            for (i=0;i<psyData[ch]->sfbActive;i++) {
11232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              psyOutChannel[ch]->sfbThresholdLdData[i] =
11242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                           fixMax(psyOutChannel[ch]->sfbThresholdLdData[i], FL2FXCONST_DBL(-0.515625f));
11252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
11262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
11292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
11322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /*
11352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        Intensity parameter intialization.
11362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project     */
11372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for(ch=0;ch<channels;ch++) {
11382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FDKmemclear(psyOutChannel[ch]->isBook,  MAX_GROUPED_SFB*sizeof(INT));
11392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FDKmemclear(psyOutChannel[ch]->isScale, MAX_GROUPED_SFB*sizeof(INT));
11402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
11412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for(ch=0;ch<channels;ch++) {
11432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT win = (isShortWindow[ch]?1:0);
11442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (!psyStatic[ch]->isLFE)
11452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        {
11462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* PNS Decision */
11472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKaacEnc_PnsDetect( &(psyConf[0].pnsConf),
11482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       pnsData[ch],
11492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       psyStatic[ch]->blockSwitchingControl.lastWindowSequence,
11502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       psyData[ch]->sfbActive,
11512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       maxSfbPerGroup[ch], /* count of Sfb which are not zero. */
11522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       psyOutChannel[ch]->sfbThresholdLdData,
11532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       psyConf[win].sfbOffset,
11542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       psyData[ch]->mdctSpectrum,
11552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       psyData[ch]->sfbMaxScaleSpec.Long,
11562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       sfbTonality[ch],
11572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       psyOutChannel[ch]->tnsInfo.order[0][0],
11582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain,
11592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive,
11602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       psyOutChannel[ch]->sfbEnergyLdData,
11612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                       psyOutChannel[ch]->noiseNrg );
11622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        } /* !isLFE */
11632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
11642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /*
11662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        stereo Processing
11672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    */
11682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if(channels == 2)
11692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
11702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        psyOutElement->toolsInfo.msDigest = MS_NONE;
11712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        psyOutElement->commonWindow       = commonWindow;
11722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (psyOutElement->commonWindow)
11732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            maxSfbPerGroup[0] = maxSfbPerGroup[1] =
11742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                              fixMax(maxSfbPerGroup[0], maxSfbPerGroup[1]);
11752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if(psyStatic[0]->blockSwitchingControl.lastWindowSequence != SHORT_WINDOW)
11772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        {
11782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* PNS preprocessing depending on ms processing: PNS not in Short Window! */
11792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKaacEnc_PreProcessPnsChannelPair(
11802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[0]->sfbActive,
11812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                (&psyData[0]->sfbEnergy)->Long,
11822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                (&psyData[1]->sfbEnergy)->Long,
11832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[0]->sfbEnergyLdData,
11842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[1]->sfbEnergyLdData,
11852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[0]->sfbEnergyMS.Long,
11862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                &(psyConf[0].pnsConf),
11872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                pnsData[0],
11882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                pnsData[1]);
11892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKaacEnc_IntensityStereoProcessing(
11912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[0]->sfbEnergy.Long,
11922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[1]->sfbEnergy.Long,
11932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[0]->mdctSpectrum,
11942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[1]->mdctSpectrum,
11952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[0]->sfbThreshold.Long,
11962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[1]->sfbThreshold.Long,
11972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[1]->sfbThresholdLdData,
11982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[0]->sfbSpreadEnergy.Long,
11992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[1]->sfbSpreadEnergy.Long,
12002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[0]->sfbEnergyLdData,
12012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[1]->sfbEnergyLdData,
12022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                &psyOutElement->toolsInfo.msDigest,
12032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutElement->toolsInfo.msMask,
12042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyConf[0].sfbCnt,
12052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyConf[0].sfbCnt,
12062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                maxSfbPerGroup[0],
12072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyConf[0].sfbOffset,
12082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyConf[0].allowIS && commonWindow,
12092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[1]->isBook,
12102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[1]->isScale,
12112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                pnsData);
12122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKaacEnc_MsStereoProcessing(
12142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData,
12152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel,
12162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[1]->isBook,
12172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                &psyOutElement->toolsInfo.msDigest,
12182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutElement->toolsInfo.msMask,
12192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[0]->sfbActive,
12202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[0]->sfbActive,
12212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                maxSfbPerGroup[0],
12222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[0]->sfbOffsets);
12232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* PNS postprocessing */
12252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKaacEnc_PostProcessPnsChannelPair(psyData[0]->sfbActive,
12262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                &(psyConf[0].pnsConf),
12272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                pnsData[0],
12282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                pnsData[1],
12292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutElement->toolsInfo.msMask,
12302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                &psyOutElement->toolsInfo.msDigest);
12312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        } else {
12332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKaacEnc_IntensityStereoProcessing(
12342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[0]->sfbEnergy.Long,
12352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[1]->sfbEnergy.Long,
12362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[0]->mdctSpectrum,
12372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[1]->mdctSpectrum,
12382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[0]->sfbThreshold.Long,
12392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[1]->sfbThreshold.Long,
12402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[1]->sfbThresholdLdData,
12412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[0]->sfbSpreadEnergy.Long,
12422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[1]->sfbSpreadEnergy.Long,
12432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[0]->sfbEnergyLdData,
12442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[1]->sfbEnergyLdData,
12452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                &psyOutElement->toolsInfo.msDigest,
12462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutElement->toolsInfo.msMask,
12472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyStatic[0]->blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt,
12482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyConf[1].sfbCnt,
12492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                maxSfbPerGroup[0],
12502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyData[0]->groupedSfbOffset,
12512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyConf[0].allowIS && commonWindow,
12522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[1]->isBook,
12532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[1]->isScale,
12542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                pnsData);
12552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            /* it's OK to pass the ".Long" arrays here. They contain grouped short data since FDKaacEnc_groupShortData() */
12572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FDKaacEnc_MsStereoProcessing( psyData,
12582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel,
12592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[1]->isBook,
12602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                &psyOutElement->toolsInfo.msDigest,
12612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutElement->toolsInfo.msMask,
12622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyStatic[0]->blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt,
12632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                hPsyConfShort->sfbCnt,
12642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                maxSfbPerGroup[0],
12652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                psyOutChannel[0]->sfbOffsets);
12662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
12672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
12682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /*
12702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    PNS Coding
12712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  */
12722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for(ch=0;ch<channels;ch++) {
12732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (psyStatic[ch]->isLFE) {
12742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          /* no PNS coding */
12752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          for(sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) {
12762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyOutChannel[ch]->noiseNrg[sfb] = NO_NOISE_PNS;
12772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
12782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      } else
12792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      {
12802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          FDKaacEnc_CodePnsChannel(psyData[ch]->sfbActive,
12812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         &(psyConf[ch].pnsConf),
12822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         pnsData[ch]->pnsFlag,
12832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         psyData[ch]->sfbEnergyLdData.Long,
12842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         psyOutChannel[ch]->noiseNrg, /* this is the energy that will be written to the bitstream */
12852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                         psyOutChannel[ch]->sfbThresholdLdData);
12862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
12872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
12882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /*
12902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        build output
12912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    */
12922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    for(ch=0;ch<channels;ch++)
12932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
12942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        INT j, grp, mask;
12952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        psyOutChannel[ch]->maxSfbPerGroup    = maxSfbPerGroup[ch];
12972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        psyOutChannel[ch]->mdctScale         = psyData[ch]->mdctScale;
12982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if(isShortWindow[ch]==0) {
13002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyOutChannel[ch]->sfbCnt         = hPsyConfLong->sfbActive;
13022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyOutChannel[ch]->sfbPerGroup    = hPsyConfLong->sfbActive;
13032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyOutChannel[ch]->lastWindowSequence = psyStatic[ch]->blockSwitchingControl.lastWindowSequence;
13042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyOutChannel[ch]->windowShape    = psyStatic[ch]->blockSwitchingControl.windowShape;
13052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
13062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        else {
13072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            INT sfbCnt = psyStatic[ch]->blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt;
13082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyOutChannel[ch]->sfbCnt         = sfbCnt;
13102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyOutChannel[ch]->sfbPerGroup    = hPsyConfShort->sfbCnt;
13112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyOutChannel[ch]->lastWindowSequence = SHORT_WINDOW;
13122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            psyOutChannel[ch]->windowShape    = SINE_WINDOW;
13132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
13142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* generate grouping mask */
13162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        mask = 0;
13172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for (grp = 0; grp < psyStatic[ch]->blockSwitchingControl.noOfGroups; grp++)
13182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        {
13192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          mask <<= 1;
13202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          for (j=1; j<psyStatic[ch]->blockSwitchingControl.groupLen[grp]; j++) {
13212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              mask = (mask<<1) | 1 ;
13222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
13232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
13242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        psyOutChannel[ch]->groupingMask = mask;
13252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* build interface */
13272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FDKmemcpy(psyOutChannel[ch]->groupLen,psyStatic[ch]->blockSwitchingControl.groupLen,MAX_NO_OF_GROUPS*sizeof(INT));
13282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FDKmemcpy(psyOutChannel[ch]->sfbEnergy,(&psyData[ch]->sfbEnergy)->Long, MAX_GROUPED_SFB*sizeof(FIXP_DBL));
13292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FDKmemcpy(psyOutChannel[ch]->sfbSpreadEnergy,(&psyData[ch]->sfbSpreadEnergy)->Long, MAX_GROUPED_SFB*sizeof(FIXP_DBL));
13302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project//        FDKmemcpy(psyOutChannel[ch]->mdctSpectrum, psyData[ch]->mdctSpectrum, (1024)*sizeof(FIXP_DBL));
13312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
13322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return AAC_ENC_OK;
13342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
13352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid FDKaacEnc_PsyClose(PSY_INTERNAL   **phPsyInternal,
13382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        PSY_OUT        **phPsyOut)
13392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
13402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    int n, i;
13412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if(phPsyInternal!=NULL) {
13442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      PSY_INTERNAL *hPsyInternal = *phPsyInternal;
13452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (hPsyInternal)
13472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      {
13482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for (i=0; i<(6); i++) {
13492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          if (hPsyInternal->pStaticChannels[i]) {
13502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if (hPsyInternal->pStaticChannels[i]->psyInputBuffer)
13512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              FreeRam_aacEnc_PsyInputBuffer(&hPsyInternal->pStaticChannels[i]->psyInputBuffer);  /* AUDIO INPUT BUFFER */
13522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FreeRam_aacEnc_PsyStatic(&hPsyInternal->pStaticChannels[i]);                         /* PSY_STATIC */
13542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
13552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
13562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for (i=0; i<(6); i++) {
13582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          if (hPsyInternal->psyElement[i])
13592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            FreeRam_aacEnc_PsyElement(&hPsyInternal->psyElement[i]);                             /* PSY_ELEMENT */
13602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
13612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        FreeRam_aacEnc_PsyInternal(phPsyInternal);
13642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
13652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
13662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (phPsyOut!=NULL) {
13682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      for (n=0; n<(1); n++) {
13692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        if (phPsyOut[n])
13702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        {
13712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          for (i=0; i<(6); i++) {
13722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if (phPsyOut[n]->pPsyOutChannels[i])
13732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              FreeRam_aacEnc_PsyOutChannel(&phPsyOut[n]->pPsyOutChannels[i]);                  /* PSY_OUT_CHANNEL */
13742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
13752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          for (i=0; i<(6); i++) {
13772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if (phPsyOut[n]->psyOutElement[i])
13782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project              FreeRam_aacEnc_PsyOutElements(&phPsyOut[n]->psyOutElement[i]);                   /* PSY_OUT_ELEMENTS */
13792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
13802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          FreeRam_aacEnc_PsyOut(&phPsyOut[n]);
13822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
13832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
13842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
13852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1386