1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* ----------------------------------------------------------------------------------------------------------- 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSoftware License for The Fraunhofer FDK AAC Codec Library for Android 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org� Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V. 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org All rights reserved. 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1. INTRODUCTION 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgThe Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgthe MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgThis FDK AAC Codec software is intended to be used on a wide variety of Android devices. 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgAAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgaudio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgindependent studies and is widely deployed. AAC has been standardized by ISO and IEC as part 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgof the MPEG specifications. 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgPatent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmay be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgindividually for the purpose of encoding or decoding bit streams in products that are compliant with 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgthe ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgthese patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftware may already be covered under those patent licenses when it is used for those licensed purposes only. 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCommercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgare also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgapplications information and documentation. 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org2. COPYRIGHT LICENSE 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgRedistribution and use in source and binary forms, with or without modification, are permitted without 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpayment of copyright license fees provided that you satisfy the following conditions: 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgYou must retain the complete text of this software license in redistributions of the FDK AAC Codec or 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgyour modifications thereto in source code form. 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgYou must retain the complete text of this software license in the documentation and/or other materials 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprovided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgYou must make available free of charge copies of the complete source code of the FDK AAC Codec and your 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmodifications thereto to recipients of copies in binary form. 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgThe name of Fraunhofer may not be used to endorse or promote products derived from this library without 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprior written permission. 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgYou may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftware or your modifications thereto. 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgYour modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.organd the date of any change. For modified versions of the FDK AAC Codec, the term 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org3. NO PATENT LICENSE 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgNO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgrespect to this software. 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgYou may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgby appropriate patent licenses. 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org4. DISCLAIMER 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgThis FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgof merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgincluding but not limited to procurement of substitute goods or services; loss of use, data, or profits, 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgor business interruption, however caused and on any theory of liability, whether in contract, strict 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgliability, or tort (including negligence), arising in any way out of the use of this software, even if 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgadvised of the possibility of such damage. 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org5. CONTACT INFORMATION 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgFraunhofer Institute for Integrated Circuits IIS 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgAttention: Audio and Multimedia Departments - FDK AAC LL 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgAm Wolfsmantel 33 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org91058 Erlangen, Germany 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgwww.iis.fraunhofer.de/amm 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgamm-info@iis.fraunhofer.de 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org----------------------------------------------------------------------------------------------------------- */ 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/******************************** MPEG Audio Encoder ************************** 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Initial author: M. Werner 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org contents/description: Threshold compensation 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org******************************************************************************/ 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "common_fix.h" 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "adj_thr_data.h" 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "adj_thr.h" 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "qc_data.h" 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sf_estim.h" 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "aacEnc_ram.h" 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define INV_INT_TAB_SIZE (8) 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const FIXP_DBL invInt[INV_INT_TAB_SIZE] = 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0x7fffffff, 0x7fffffff, 0x40000000, 0x2aaaaaaa, 0x20000000, 0x19999999, 0x15555555, 0x12492492 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define INV_SQRT4_TAB_SIZE (8) 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const FIXP_DBL invSqrt4[INV_SQRT4_TAB_SIZE] = 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0x7fffffff, 0x7fffffff, 0x6ba27e65, 0x61424bb5, 0x5a827999, 0x55994845, 0x51c8e33c, 0x4eb160d1 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*static const INT invRedExp = 4;*/ 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const FIXP_DBL SnrLdMin1 = (FIXP_DBL)0xfcad0ddf; /*FL2FXCONST_DBL(FDKlog(0.316)/FDKlog(2.0)/LD_DATA_SCALING);*/ 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const FIXP_DBL SnrLdMin2 = (FIXP_DBL)0x0351e1a2; /*FL2FXCONST_DBL(FDKlog(3.16) /FDKlog(2.0)/LD_DATA_SCALING);*/ 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const FIXP_DBL SnrLdFac = (FIXP_DBL)0xff5b2c3e; /*FL2FXCONST_DBL(FDKlog(0.8) /FDKlog(2.0)/LD_DATA_SCALING);*/ 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const FIXP_DBL SnrLdMin3 = (FIXP_DBL)0xfe000000; /*FL2FXCONST_DBL(FDKlog(0.5) /FDKlog(2.0)/LD_DATA_SCALING);*/ 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const FIXP_DBL SnrLdMin4 = (FIXP_DBL)0x02000000; /*FL2FXCONST_DBL(FDKlog(2.0) /FDKlog(2.0)/LD_DATA_SCALING);*/ 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const FIXP_DBL SnrLdMin5 = (FIXP_DBL)0xfc000000; /*FL2FXCONST_DBL(FDKlog(0.25) /FDKlog(2.0)/LD_DATA_SCALING);*/ 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgThe bits2Pe factors are choosen for the case that some times 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgthe crash recovery strategy will be activated once. 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org*/ 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypedef struct { 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT bitrate; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LONG bits2PeFactor_mono; 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LONG bits2PeFactor_mono_slope; 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LONG bits2PeFactor_stereo; 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LONG bits2PeFactor_stereo_slope; 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LONG bits2PeFactor_mono_scfOpt; 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LONG bits2PeFactor_mono_scfOpt_slope; 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LONG bits2PeFactor_stereo_scfOpt; 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LONG bits2PeFactor_stereo_scfOpt_slope; 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} BIT_PE_SFAC; 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypedef struct { 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT sampleRate; 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const BIT_PE_SFAC * pPeTab; 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT nEntries; 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} BITS2PE_CFG_TAB; 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const BIT_PE_SFAC S_Bits2PeTab16000[] = { 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 10000, 0x228F5C29, 0x02FEF55D, 0x1D70A3D7, 0x09BC9D6D, 0x228F5C29, 0x02FEF55D, 0x1C28F5C3, 0x0CBB92CA}, 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 24000, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413}, 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 32000, 0x247AE148, 0x11B1D92B, 0x23851EB8, 0x01F75105, 0x247AE148, 0x110A137F, 0x23851EB8, 0x01F75105}, 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 48000, 0x2D1EB852, 0x6833C600, 0x247AE148, 0x014F8B59, 0x2CCCCCCD, 0x68DB8BAC, 0x247AE148, 0x01F75105}, 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 64000, 0x60000000, 0x00000000, 0x251EB852, 0x154C985F, 0x60000000, 0x00000000, 0x2570A3D7, 0x154C985F}, 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 96000, 0x60000000, 0x00000000, 0x39EB851F, 0x088509C0, 0x60000000, 0x00000000, 0x3A3D70A4, 0x088509C0}, 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {128000, 0x60000000, 0x00000000, 0x423D70A4, 0x18A43BB4, 0x60000000, 0x00000000, 0x428F5C29, 0x181E03F7}, 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {148000, 0x60000000, 0x00000000, 0x5147AE14, 0x00000000, 0x60000000, 0x00000000, 0x5147AE14, 0x00000000} 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const BIT_PE_SFAC S_Bits2PeTab22050[] = { 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 16000, 0x1a8f5c29, 0x1797cc3a, 0x128f5c29, 0x18e75793, 0x175c28f6, 0x221426fe, 0x00000000, 0x5a708ede}, 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 24000, 0x2051eb85, 0x092ccf6c, 0x18a3d70a, 0x13a92a30, 0x1fae147b, 0xbcbe61d, 0x16147ae1, 0x18e75793}, 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 32000, 0x228f5c29, 0x029f16b1, 0x1d70a3d7, 0x088509c0, 0x228f5c29, 0x29f16b1, 0x1c28f5c3, 0x0b242071}, 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 48000, 0x23d70a3d, 0x014f8b59, 0x2199999a, 0x03eea20a, 0x23d70a3d, 0x14f8b59, 0x2199999a, 0x03eea20a}, 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 64000, 0x247ae148, 0x08d8ec96, 0x23851eb8, 0x00fba882, 0x247ae148, 0x88509c0, 0x23851eb8, 0x00fba882}, 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 96000, 0x2d1eb852, 0x3419e300, 0x247ae148, 0x00a7c5ac, 0x2ccccccd, 0x346dc5d6, 0x247ae148, 0x00fba882}, 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {128000, 0x60000000, 0x00000000, 0x251eb852, 0x029f16b1, 0x60000000, 0x00000000, 0x2570a3d7, 0x009f16b1}, 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {148000, 0x60000000, 0x00000000, 0x26b851ec, 0x00000000, 0x60000000, 0x00000000, 0x270a3d71, 0x00000000} 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const BIT_PE_SFAC S_Bits2PeTab24000[] = { 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 16000, 0x19eb851f, 0x13a92a30, 0x1147ae14, 0x164840e1, 0x1999999a, 0x12599ed8, 0x00000000, 0x46c764ae}, 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 24000, 0x1eb851ec, 0x0d1b7176, 0x16b851ec, 0x18e75793, 0x1e147ae1, 0x0fba8827, 0x1147ae14, 0x2c9081c3}, 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 32000, 0x21eb851f, 0x049667b6, 0x1ccccccd, 0x07357e67, 0x21eb851f, 0x03eea20a, 0x1c28f5c3, 0x07357e67}, 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 48000, 0x2428f5c3, 0x014f8b59, 0x2051eb85, 0x053e2d62, 0x23d70a3d, 0x01f75105, 0x1fae147b, 0x07357e67}, 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 64000, 0x24cccccd, 0x05e5f30e, 0x22e147ae, 0x01a36e2f, 0x24cccccd, 0x05e5f30e, 0x23333333, 0x014f8b59}, 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 96000, 0x2a8f5c29, 0x24b33db0, 0x247ae148, 0x00fba882, 0x2a8f5c29, 0x26fe718b, 0x247ae148, 0x00fba882}, 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {128000, 0x4e666666, 0x1cd5f99c, 0x2570a3d7, 0x010c6f7a, 0x50a3d70a, 0x192a7371, 0x2570a3d7, 0x010c6f7a}, 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {148000, 0x60000000, 0x00000000, 0x26147ae1, 0x00000000, 0x60000000, 0x00000000, 0x26147ae1, 0x00000000} 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const BIT_PE_SFAC S_Bits2PeTab32000[] = { 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 16000, 0x1199999a, 0x20c49ba6, 0x00000000, 0x4577d955, 0x00000000, 0x60fe4799, 0x00000000, 0x00000000}, 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 24000, 0x1999999a, 0x0fba8827, 0x10f5c28f, 0x1b866e44, 0x17ae147b, 0x0fba8827, 0x00000000, 0x4d551d69}, 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 32000, 0x1d70a3d7, 0x07357e67, 0x17ae147b, 0x09d49518, 0x1b851eb8, 0x0a7c5ac4, 0x12e147ae, 0x110a137f}, 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 48000, 0x20f5c28f, 0x049667b6, 0x1c7ae148, 0x053e2d62, 0x20a3d70a, 0x053e2d62, 0x1b333333, 0x05e5f30e}, 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 64000, 0x23333333, 0x029f16b1, 0x1f0a3d71, 0x02f2f987, 0x23333333, 0x029f16b1, 0x1e147ae1, 0x03eea20a}, 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 96000, 0x25c28f5c, 0x2c3c9eed, 0x21eb851f, 0x01f75105, 0x25c28f5c, 0x0a7c5ac4, 0x21eb851f, 0x01a36e2f}, 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {128000, 0x50f5c28f, 0x18a43bb4, 0x23d70a3d, 0x010c6f7a, 0x30000000, 0x168b5cc0, 0x23851eb8, 0x0192a737}, 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {148000, 0x60000000, 0x00000000, 0x247ae148, 0x00dfb23b, 0x3dc28f5c, 0x300f4aaf, 0x247ae148, 0x01bf6476}, 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {160000, 0x60000000, 0xb15b5740, 0x24cccccd, 0x053e2d62, 0x4f5c28f6, 0xbefd0072, 0x251eb852, 0x04fb1184}, 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {200000, 0x00000000, 0x00000000, 0x2b333333, 0x0836be91, 0x00000000, 0x00000000, 0x2b333333, 0x0890390f}, 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {320000, 0x00000000, 0x00000000, 0x4947ae14, 0x00000000, 0x00000000, 0x00000000, 0x4a8f5c29, 0x00000000} 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const BIT_PE_SFAC S_Bits2PeTab44100[] = { 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 16000, 0x10a3d70a, 0x1797cc3a, 0x00000000, 0x00000000, 0x00000000, 0x59210386, 0x00000000, 0x00000000}, 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 24000, 0x16666666, 0x1797cc3a, 0x00000000, 0x639d5e4a, 0x15c28f5c, 0x12599ed8, 0x00000000, 0x5bc01a37}, 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 32000, 0x1c28f5c3, 0x049667b6, 0x1851eb85, 0x049667b6, 0x1a3d70a4, 0x088509c0, 0x16666666, 0x053e2d62}, 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 48000, 0x1e666666, 0x05e5f30e, 0x1a8f5c29, 0x049667b6, 0x1e666666, 0x05e5f30e, 0x18f5c28f, 0x05e5f30e}, 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 64000, 0x2147ae14, 0x0346dc5d, 0x1ccccccd, 0x02f2f987, 0x2147ae14, 0x02f2f987, 0x1bd70a3d, 0x039abf34}, 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 96000, 0x247ae148, 0x068db8bb, 0x1fae147b, 0x029f16b1, 0x2428f5c3, 0x0639d5e5, 0x1f5c28f6, 0x029f16b1}, 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {128000, 0x2ae147ae, 0x1b435265, 0x223d70a4, 0x0192a737, 0x2a3d70a4, 0x1040bfe4, 0x21eb851f, 0x0192a737}, 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {148000, 0x3b851eb8, 0x2832069c, 0x23333333, 0x00dfb23b, 0x3428f5c3, 0x2054c288, 0x22e147ae, 0x00dfb23b}, 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {160000, 0x4a3d70a4, 0xc32ebe5a, 0x23851eb8, 0x01d5c316, 0x40000000, 0xcb923a2b, 0x23333333, 0x01d5c316}, 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {200000, 0x00000000, 0x00000000, 0x25c28f5c, 0x0713f078, 0x00000000, 0x00000000, 0x2570a3d7, 0x072a4f17}, 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {320000, 0x00000000, 0x00000000, 0x3fae147b, 0x00000000, 0x00000000, 0x00000000, 0x3fae147b, 0x00000000} 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const BIT_PE_SFAC S_Bits2PeTab48000[] = { 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 16000, 0x0f5c28f6, 0x31ceaf25, 0x00000000, 0x00000000, 0x00000000, 0x74a771c9, 0x00000000, 0x00000000}, 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 24000, 0x1b851eb8, 0x029f16b1, 0x00000000, 0x663c74fb, 0x1c7ae148, 0xe47991bd, 0x00000000, 0x49667b5f}, 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 32000, 0x1c28f5c3, 0x029f16b1, 0x18f5c28f, 0x07357e67, 0x15c28f5c, 0x0f12c27a, 0x11eb851f, 0x13016484}, 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 48000, 0x1d70a3d7, 0x053e2d62, 0x1c7ae148, 0xfe08aefc, 0x1d1eb852, 0x068db8bb, 0x1b333333, 0xfeb074a8}, 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 64000, 0x20000000, 0x03eea20a, 0x1b851eb8, 0x0346dc5d, 0x2051eb85, 0x0346dc5d, 0x1a8f5c29, 0x039abf34}, 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 96000, 0x23d70a3d, 0x053e2d62, 0x1eb851ec, 0x029f16b1, 0x23851eb8, 0x04ea4a8c, 0x1e147ae1, 0x02f2f987}, 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {128000, 0x28f5c28f, 0x14727dcc, 0x2147ae14, 0x0218def4, 0x2851eb85, 0x0e27e0f0, 0x20f5c28f, 0x0218def4}, 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {148000, 0x3570a3d7, 0x1cd5f99c, 0x228f5c29, 0x01bf6476, 0x30f5c28f, 0x18777e75, 0x223d70a4, 0x01bf6476}, 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {160000, 0x40000000, 0xcb923a2b, 0x23333333, 0x0192a737, 0x39eb851f, 0xd08d4bae, 0x22e147ae, 0x0192a737}, 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {200000, 0x00000000, 0x00000000, 0x251eb852, 0x06775a1b, 0x00000000, 0x00000000, 0x24cccccd, 0x06a4175a}, 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org {320000, 0x00000000, 0x00000000, 0x3ccccccd, 0x00000000, 0x00000000, 0x00000000, 0x3d1eb852, 0x00000000} 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const BITS2PE_CFG_TAB bits2PeConfigTab[] = { 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 16000, S_Bits2PeTab16000, sizeof(S_Bits2PeTab16000)/sizeof(BIT_PE_SFAC) }, 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 22050, S_Bits2PeTab22050, sizeof(S_Bits2PeTab22050)/sizeof(BIT_PE_SFAC) }, 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 24000, S_Bits2PeTab24000, sizeof(S_Bits2PeTab24000)/sizeof(BIT_PE_SFAC) }, 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 32000, S_Bits2PeTab32000, sizeof(S_Bits2PeTab32000)/sizeof(BIT_PE_SFAC) }, 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 44100, S_Bits2PeTab44100, sizeof(S_Bits2PeTab44100)/sizeof(BIT_PE_SFAC) }, 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 48000, S_Bits2PeTab48000, sizeof(S_Bits2PeTab48000)/sizeof(BIT_PE_SFAC) } 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* values for avoid hole flag */ 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum _avoid_hole_state { 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NO_AH =0, 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AH_INACTIVE =1, 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AH_ACTIVE =2 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Q format definitions */ 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define Q_BITFAC (24) /* Q scaling used in FDKaacEnc_bitresCalcBitFac() calculation */ 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define Q_AVGBITS (17) /* scale bit values */ 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/***************************************************************************** 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functionname: FDKaacEnc_InitBits2PeFactor 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org description: retrieve bits2PeFactor from table 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org*****************************************************************************/ 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void FDKaacEnc_InitBits2PeFactor( 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL *bits2PeFactor_m, 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT *bits2PeFactor_e, 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT bitRate, 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT nChannels, 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT sampleRate, 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT advancedBitsToPe, 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT invQuant 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ) 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* default bits2pe factor */ 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL bit2PE_m = FL2FXCONST_DBL(1.18f/(1<<(1))); 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT bit2PE_e = 1; 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* make use of advanced bits to pe factor table */ 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (advancedBitsToPe) { 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const BIT_PE_SFAC *peTab = NULL; 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT size = 0; 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Get correct table entry */ 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i=0; i<(INT)(sizeof(bits2PeConfigTab)/sizeof(BITS2PE_CFG_TAB)); i++) { 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sampleRate >= bits2PeConfigTab[i].sampleRate) { 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org peTab = bits2PeConfigTab[i].pPeTab; 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size = bits2PeConfigTab[i].nEntries; 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( (peTab!=NULL) && (size!=0) ) { 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT startB = -1; 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LONG startPF = 0; 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LONG peSlope = 0; 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* stereo or mono mode and invQuant used or not */ 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i=0; i<size-1; i++) 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((peTab[i].bitrate<=bitRate) && ((peTab[i+1].bitrate>bitRate) || ((i==size-2)) )) 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (nChannels==1) 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org startPF = (!invQuant) ? peTab[i].bits2PeFactor_mono : peTab[i].bits2PeFactor_mono_scfOpt; 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org peSlope = (!invQuant) ? peTab[i].bits2PeFactor_mono_slope : peTab[i].bits2PeFactor_mono_scfOpt_slope; 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*endPF = (!invQuant) ? peTab[i+1].bits2PeFactor_mono : peTab[i+1].bits2PeFactor_mono_scfOpt; 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org endB=peTab[i+1].bitrate;*/ 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org startB=peTab[i].bitrate; 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org startPF = (!invQuant) ? peTab[i].bits2PeFactor_stereo : peTab[i].bits2PeFactor_stereo_scfOpt; 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org peSlope = (!invQuant) ? peTab[i].bits2PeFactor_stereo_slope : peTab[i].bits2PeFactor_stereo_scfOpt_slope; 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*endPF = (!invQuant) ? peTab[i+1].bits2PeFactor_stereo : peTab[i+1].bits2PeFactor_stereo_scfOpt; 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org endB=peTab[i+1].bitrate;*/ 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org startB=peTab[i].bitrate; 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } /* for i */ 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* if a configuration is available */ 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (startB!=-1) { 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* linear interpolate to actual PEfactor */ 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL peFac = fMult((FIXP_DBL)(bitRate-startB)<<14, (FIXP_DBL)peSlope) << 2; 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL bit2PE = peFac + (FIXP_DBL)startPF; /* startPF_float = startPF << 2 */ 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* sanity check if bits2pe value is high enough */ 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( bit2PE >= (FL2FXCONST_DBL(0.35f) >> 2) ) { 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bit2PE_m = bit2PE; 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bit2PE_e = 2; /* table is fixed scaled */ 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } /* br */ 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } /* sr */ 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } /* advancedBitsToPe */ 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* return bits2pe factor */ 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *bits2PeFactor_m = bit2PE_m; 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *bits2PeFactor_e = bit2PE_e; 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/***************************************************************************** 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfunctionname: FDKaacEnc_bits2pe2 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdescription: convert from bits to pe 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org*****************************************************************************/ 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INT FDKaacEnc_bits2pe2( 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT bits, 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const FIXP_DBL factor_m, 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT factor_e 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ) 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (INT)(fMult(factor_m, (FIXP_DBL)(bits<<Q_AVGBITS)) >> (Q_AVGBITS-factor_e)); 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/***************************************************************************** 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfunctionname: FDKaacEnc_calcThreshExp 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdescription: loudness calculation (threshold to the power of redExp) 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org*****************************************************************************/ 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void FDKaacEnc_calcThreshExp(FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org QC_OUT_CHANNEL* qcOutChannel[(2)], 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PSY_OUT_CHANNEL* psyOutChannel[(2)], 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT nChannels) 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT ch, sfb, sfbGrp; 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL thrExpLdData; 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (ch=0; ch<nChannels; ch++) { 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup) { 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org thrExpLdData = psyOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb]>>2 ; 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org thrExp[ch][sfbGrp+sfb] = CalcInvLdData(thrExpLdData); 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/***************************************************************************** 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org functionname: FDKaacEnc_adaptMinSnr 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org description: reduce minSnr requirements for bands with relative low energies 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org*****************************************************************************/ 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void FDKaacEnc_adaptMinSnr(QC_OUT_CHANNEL *qcOutChannel[(2)], 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PSY_OUT_CHANNEL *psyOutChannel[(2)], 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MINSNR_ADAPT_PARAM *msaParam, 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT nChannels) 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT ch, sfb, sfbGrp, nSfb; 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL avgEnLD64, dbRatio, minSnrRed; 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL minSnrLimitLD64 = FL2FXCONST_DBL(-0.00503012648262f); /* ld64(0.8f) */ 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL nSfbLD64; 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL accu; 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (ch=0; ch<nChannels; ch++) { 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* calc average energy per scalefactor band */ 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nSfb = 0; 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org accu = FL2FXCONST_DBL(0.0f); 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfbGrp=0; sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org accu += psyOutChannel[ch]->sfbEnergy[sfbGrp+sfb]>>6; 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nSfb++; 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((accu == FL2FXCONST_DBL(0.0f)) || (nSfb == 0)) { 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org avgEnLD64 = FL2FXCONST_DBL(-1.0f); 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nSfbLD64 = CalcLdInt(nSfb); 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org avgEnLD64 = CalcLdData(accu); 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org avgEnLD64 = avgEnLD64 + FL2FXCONST_DBL(0.09375f) - nSfbLD64; /* 0.09375f: compensate shift with 6 */ 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* reduce minSnr requirement by minSnr^minSnrRed dependent on avgEn/sfbEn */ 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfbGrp=0; sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( (msaParam->startRatio + qcOutChannel[ch]->sfbEnergyLdData[sfbGrp+sfb]) < avgEnLD64 ) { 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dbRatio = fMult((avgEnLD64 - qcOutChannel[ch]->sfbEnergyLdData[sfbGrp+sfb]),FL2FXCONST_DBL(0.3010299956f)); /* scaled by (1.0f/(10.0f*64.0f)) */ 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org minSnrRed = msaParam->redOffs + fMult(msaParam->redRatioFac,dbRatio); /* scaled by 1.0f/64.0f*/ 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org minSnrRed = fixMax(minSnrRed, msaParam->maxRed); /* scaled by 1.0f/64.0f*/ 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp+sfb] = (fMult(qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp+sfb],minSnrRed)) << 6; 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp+sfb] = fixMin(minSnrLimitLD64, qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp+sfb]); 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/***************************************************************************** 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfunctionname: FDKaacEnc_initAvoidHoleFlag 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdescription: determine bands where avoid hole is not necessary resp. possible 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org*****************************************************************************/ 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void FDKaacEnc_initAvoidHoleFlag(QC_OUT_CHANNEL *qcOutChannel[(2)], 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PSY_OUT_CHANNEL *psyOutChannel[(2)], 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UCHAR ahFlag[(2)][MAX_GROUPED_SFB], 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct TOOLSINFO *toolsInfo, 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT nChannels, 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const PE_DATA *peData, 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AH_PARAM *ahParam) 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT ch, sfb, sfbGrp; 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL sfbEn, sfbEnm1; 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL sfbEnLdData; 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL avgEnLdData; 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* decrease spread energy by 3dB for long blocks, resp. 2dB for shorts 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (avoid more holes in long blocks) */ 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (ch=0; ch<nChannels; ch++) { 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT sfbGrp, sfb; 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org QC_OUT_CHANNEL* qcOutChan = qcOutChannel[ch]; 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (psyOutChannel[ch]->lastWindowSequence != SHORT_WINDOW) { 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup) 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChan->sfbSpreadEnergy[sfbGrp+sfb] >>= 1 ; 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup) 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChan->sfbSpreadEnergy[sfbGrp+sfb] = 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fMult(FL2FXCONST_DBL(0.63f), 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChan->sfbSpreadEnergy[sfbGrp+sfb]) ; 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* increase minSnr for local peaks, decrease it for valleys */ 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ahParam->modifyMinSnr) { 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(ch=0; ch<nChannels; ch++) { 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org QC_OUT_CHANNEL* qcOutChan = qcOutChannel[ch]; 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup){ 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL sfbEnp1, avgEn; 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sfb > 0) 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp+sfb-1]; 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp+sfb]; 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sfb < psyOutChannel[ch]->maxSfbPerGroup-1) 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp+sfb+1]; 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp+sfb]; 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org avgEn = (sfbEnm1>>1) + (sfbEnp1>>1); 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org avgEnLdData = CalcLdData(avgEn); 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sfbEn = qcOutChan->sfbEnergy[sfbGrp+sfb]; 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sfbEnLdData = qcOutChan->sfbEnergyLdData[sfbGrp+sfb]; 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* peak ? */ 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sfbEn > avgEn) { 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL tmpMinSnrLdData; 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (psyOutChannel[ch]->lastWindowSequence==LONG_WINDOW) 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmpMinSnrLdData = fixMax( SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData), (FIXP_DBL)SnrLdMin1 ) ; 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmpMinSnrLdData = fixMax( SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData), (FIXP_DBL)SnrLdMin3 ) ; 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] = 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fixMin(qcOutChan->sfbMinSnrLdData[sfbGrp+sfb], tmpMinSnrLdData); 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* valley ? */ 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( ((sfbEnLdData+(FIXP_DBL)SnrLdMin4) < (FIXP_DBL)avgEnLdData) && (sfbEn > FL2FXCONST_DBL(0.0)) ) { 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL tmpMinSnrLdData = avgEnLdData - sfbEnLdData -(FIXP_DBL)SnrLdMin4 + qcOutChan->sfbMinSnrLdData[sfbGrp+sfb]; 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmpMinSnrLdData = fixMin((FIXP_DBL)SnrLdFac, tmpMinSnrLdData); 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] = fixMin(tmpMinSnrLdData, 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (FIXP_DBL)(qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] + SnrLdMin2 )); 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* stereo: adapt the minimum requirements sfbMinSnr of mid and 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org side channels to avoid spending unnoticable bits */ 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (nChannels == 2) { 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org QC_OUT_CHANNEL* qcOutChanM = qcOutChannel[0]; 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org QC_OUT_CHANNEL* qcOutChanS = qcOutChannel[1]; 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PSY_OUT_CHANNEL* psyOutChanM = psyOutChannel[0]; 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(sfbGrp = 0;sfbGrp < psyOutChanM->sfbCnt;sfbGrp+= psyOutChanM->sfbPerGroup){ 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfb=0; sfb<psyOutChanM->maxSfbPerGroup; sfb++) { 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (toolsInfo->msMask[sfbGrp+sfb]) { 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL maxSfbEnLd = fixMax(qcOutChanM->sfbEnergyLdData[sfbGrp+sfb],qcOutChanS->sfbEnergyLdData[sfbGrp+sfb]); 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL maxThrLd, sfbMinSnrTmpLd; 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( ((SnrLdMin5>>1) + (maxSfbEnLd>>1) + (qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb]>>1)) <= FL2FXCONST_DBL(-0.5f)) 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org maxThrLd = FL2FXCONST_DBL(-1.0f) ; 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org maxThrLd = SnrLdMin5 + maxSfbEnLd + qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb]; 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qcOutChanM->sfbEnergy[sfbGrp+sfb] > FL2FXCONST_DBL(0.0f)) 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sfbMinSnrTmpLd = maxThrLd - qcOutChanM->sfbEnergyLdData[sfbGrp+sfb]; 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f); 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb] = fixMax(qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb],sfbMinSnrTmpLd); 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb] <= FL2FXCONST_DBL(0.0f)) 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb] = fixMin(qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb], (FIXP_DBL)SnrLdFac); 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qcOutChanS->sfbEnergy[sfbGrp+sfb] > FL2FXCONST_DBL(0.0f)) 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sfbMinSnrTmpLd = maxThrLd - qcOutChanS->sfbEnergyLdData[sfbGrp+sfb]; 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f); 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb] = fixMax(qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb],sfbMinSnrTmpLd); 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb] <= FL2FXCONST_DBL(0.0f)) 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb] = fixMin(qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb],(FIXP_DBL)SnrLdFac); 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qcOutChanM->sfbEnergy[sfbGrp+sfb]>qcOutChanM->sfbSpreadEnergy[sfbGrp+sfb]) 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChanS->sfbSpreadEnergy[sfbGrp+sfb] = 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fMult(qcOutChanS->sfbEnergy[sfbGrp+sfb], FL2FXCONST_DBL(0.9f)); 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (qcOutChanS->sfbEnergy[sfbGrp+sfb]>qcOutChanS->sfbSpreadEnergy[sfbGrp+sfb]) 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChanM->sfbSpreadEnergy[sfbGrp+sfb] = 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fMult(qcOutChanM->sfbEnergy[sfbGrp+sfb], FL2FXCONST_DBL(0.9f)); 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(ch=0; ch<nChannels; ch++) { 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org QC_OUT_CHANNEL *qcOutChan = qcOutChannel[ch]; 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PSY_OUT_CHANNEL *psyOutChan = psyOutChannel[ch]; 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){ 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) { 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((qcOutChan->sfbSpreadEnergy[sfbGrp+sfb] > qcOutChan->sfbEnergy[sfbGrp+sfb]) 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || (qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] > FL2FXCONST_DBL(0.0f))) { 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ahFlag[ch][sfbGrp+sfb] = NO_AH; 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ahFlag[ch][sfbGrp+sfb] = AH_INACTIVE; 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \brief Calculate constants that do not change during successive pe calculations. 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param peData Pointer to structure containing PE data of current element. 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding nChannels elements. 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding nChannels elements. 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param nChannels Number of channels in element. 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param peOffset Fixed PE offset defined while FDKaacEnc_AdjThrInit() depending on bitrate. 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return void 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid FDKaacEnc_preparePe(PE_DATA *peData, 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PSY_OUT_CHANNEL* psyOutChannel[(2)], 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org QC_OUT_CHANNEL* qcOutChannel[(2)], 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT nChannels, 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT peOffset) 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT ch; 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(ch=0; ch<nChannels; ch++) { 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PSY_OUT_CHANNEL *psyOutChan = psyOutChannel[ch]; 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FDKaacEnc_prepareSfbPe(&peData->peChannelData[ch], 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org psyOutChan->sfbEnergyLdData, 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org psyOutChan->sfbThresholdLdData, 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChannel[ch]->sfbFormFactorLdData, 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org psyOutChan->sfbOffsets, 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org psyOutChan->sfbCnt, 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org psyOutChan->sfbPerGroup, 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org psyOutChan->maxSfbPerGroup); 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org peData->offset = peOffset; 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \brief Calculate weighting factor for threshold adjustment. 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Calculate weighting factor to be applied at energies and thresholds in ld64 format. 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param peData, Pointer to PE data in current element. 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding nChannels elements. 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding nChannels elements. 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param toolsInfo Pointer to tools info struct of current element. 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param adjThrStateElement Pointer to ATS_ELEMENT holding enFacPatch states. 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param nChannels Number of channels in element. 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param usePatchTool Apply the weighting tool 0 (no) else (yes). 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return void 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid FDKaacEnc_calcWeighting(PE_DATA *peData, 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PSY_OUT_CHANNEL* psyOutChannel[(2)], 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org QC_OUT_CHANNEL* qcOutChannel[(2)], 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct TOOLSINFO *toolsInfo, 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ATS_ELEMENT* adjThrStateElement, 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT nChannels, 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT usePatchTool) 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int ch, noShortWindowInFrame = TRUE; 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT exePatchM = 0; 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (ch=0; ch<nChannels; ch++) { 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (psyOutChannel[ch]->lastWindowSequence == SHORT_WINDOW) { 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org noShortWindowInFrame = FALSE; 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FDKmemclear(qcOutChannel[ch]->sfbEnFacLd, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (usePatchTool==0) { 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; /* tool is disabled */ 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (ch=0; ch<nChannels; ch++) { 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PSY_OUT_CHANNEL *psyOutChan = psyOutChannel[ch]; 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (noShortWindowInFrame) { /* retain energy ratio between blocks of different length */ 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL nrgSum14, nrgSum12, nrgSum34, nrgTotal; 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL nrgFacLd_14, nrgFacLd_12, nrgFacLd_34; 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT usePatch, exePatch; 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int sfb, sfbGrp, nLinesSum = 0; 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nrgSum14 = nrgSum12 = nrgSum34 = nrgTotal = FL2FXCONST_DBL(0.f); 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* calculate flatness of audible spectrum, i.e. spectrum above masking threshold. */ 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL nrgFac12 = CalcInvLdData(psyOutChan->sfbEnergyLdData[sfbGrp+sfb]>>1); /* nrg^(1/2) */ 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FIXP_DBL nrgFac14 = CalcInvLdData(psyOutChan->sfbEnergyLdData[sfbGrp+sfb]>>2); /* nrg^(1/4) */ 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* maximal number of bands is 64, results scaling factor 6 */ 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nLinesSum += peData->peChannelData[ch].sfbNLines[sfbGrp+sfb]; /* relevant lines */ 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nrgTotal += ( psyOutChan->sfbEnergy[sfbGrp+sfb] >> 6 ); /* sum up nrg */ 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nrgSum12 += ( nrgFac12 >> 6 ); /* sum up nrg^(2/4) */ 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nrgSum14 += ( nrgFac14 >> 6 ); /* sum up nrg^(1/4) */ 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nrgSum34 += ( fMult(nrgFac14, nrgFac12) >> 6 ); /* sum up nrg^(3/4) */ 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nrgTotal = CalcLdData(nrgTotal); /* get ld64 of total nrg */ 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nrgFacLd_14 = CalcLdData(nrgSum14) - nrgTotal; /* ld64(nrgSum14/nrgTotal) */ 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nrgFacLd_12 = CalcLdData(nrgSum12) - nrgTotal; /* ld64(nrgSum12/nrgTotal) */ 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nrgFacLd_34 = CalcLdData(nrgSum34) - nrgTotal; /* ld64(nrgSum34/nrgTotal) */ 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org adjThrStateElement->chaosMeasureEnFac[ch] = FDKmax( FL2FXCONST_DBL(0.1875f), fDivNorm(nLinesSum,psyOutChan->sfbOffsets[psyOutChan->sfbCnt]) ); 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usePatch = (adjThrStateElement->chaosMeasureEnFac[ch] > FL2FXCONST_DBL(0.78125f)); 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exePatch = ((usePatch) && (adjThrStateElement->lastEnFacPatch[ch])); 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT sfbExePatch; 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* for MS coupled SFBs, also execute patch in side channel if done in mid channel */ 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((ch == 1) && (toolsInfo->msMask[sfbGrp+sfb])) { 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sfbExePatch = exePatchM; 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sfbExePatch = exePatch; 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( (sfbExePatch) && (psyOutChan->sfbEnergy[sfbGrp+sfb]>FL2FXCONST_DBL(0.f)) ) 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* execute patch based on spectral flatness calculated above */ 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (adjThrStateElement->chaosMeasureEnFac[ch] > FL2FXCONST_DBL(0.8125f)) { 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb] = ( (nrgFacLd_14 + (psyOutChan->sfbEnergyLdData[sfbGrp+sfb]+(psyOutChan->sfbEnergyLdData[sfbGrp+sfb]>>1)))>>1 ); /* sfbEnergy^(3/4) */ 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (adjThrStateElement->chaosMeasureEnFac[ch] > FL2FXCONST_DBL(0.796875f)) { 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb] = ( (nrgFacLd_12 + psyOutChan->sfbEnergyLdData[sfbGrp+sfb])>>1 ); /* sfbEnergy^(2/4) */ 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb] = ( (nrgFacLd_34 + (psyOutChan->sfbEnergyLdData[sfbGrp+sfb]>>1))>>1 ); /* sfbEnergy^(1/4) */ 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb] = fixMin(qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb],(FIXP_DBL)0); 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } /* sfb loop */ 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org adjThrStateElement->lastEnFacPatch[ch] = usePatch; 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exePatchM = exePatch; 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* !noShortWindowInFrame */ 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org adjThrStateElement->chaosMeasureEnFac[ch] = FL2FXCONST_DBL(0.75f); 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org adjThrStateElement->lastEnFacPatch[ch] = TRUE; /* allow use of sfbEnFac patch in upcoming frame */ 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } /* ch loop */ 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/***************************************************************************** 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfunctionname: FDKaacEnc_calcPe 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdescription: calculate pe for both channels 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org*****************************************************************************/ 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid FDKaacEnc_calcPe(PSY_OUT_CHANNEL* psyOutChannel[(2)], 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org QC_OUT_CHANNEL* qcOutChannel[(2)], 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PE_DATA *peData, 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT nChannels) 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT ch; 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org peData->pe = peData->offset; 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org peData->constPart = 0; 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org peData->nActiveLines = 0; 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(ch=0; ch<nChannels; ch++) { 750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch]; 751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FDKaacEnc_calcSfbPe(&peData->peChannelData[ch], 752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChannel[ch]->sfbWeightedEnergyLdData, 753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org qcOutChannel[ch]->sfbThresholdLdData, 754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org psyOutChannel[ch]->sfbCnt, 755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org psyOutChannel[ch]->sfbPerGroup, 756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org psyOutChannel[ch]->maxSfbPerGroup, 757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org psyOutChannel[ch]->isBook, 758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org psyOutChannel[ch]->isScale); 759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org peData->pe += peChanData->pe; 761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org peData->constPart += peChanData->constPart; 762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org peData->nActiveLines += peChanData->nActiveLines; 763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid FDKaacEnc_peCalculation(PE_DATA *peData, 767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PSY_OUT_CHANNEL* psyOutChannel[(2)], 768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org QC_OUT_CHANNEL* qcOutChannel[(2)], 769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct TOOLSINFO *toolsInfo, 770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ATS_ELEMENT* adjThrStateElement, 771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT nChannels) 772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* constants that will not change during successive pe calculations */ 774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FDKaacEnc_preparePe(peData, psyOutChannel, qcOutChannel, nChannels, adjThrStateElement->peOffset); 775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* calculate weighting factor for threshold adjustment */ 777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FDKaacEnc_calcWeighting(peData, psyOutChannel, qcOutChannel, toolsInfo, adjThrStateElement, nChannels, 1); 778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no weighting of threholds and energies for mlout */ 780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* weight energies and thresholds */ 781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int ch; 782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (ch=0; ch<nChannels; ch++) { 783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int sfb, sfbGrp; 785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org QC_OUT_CHANNEL* pQcOutCh = qcOutChannel[ch]; 786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { 788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { 789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pQcOutCh->sfbWeightedEnergyLdData[sfb+sfbGrp] = pQcOutCh->sfbEnergyLdData[sfb+sfbGrp] - pQcOutCh->sfbEnFacLd[sfb+sfbGrp]; 790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pQcOutCh->sfbThresholdLdData[sfb+sfbGrp] -= pQcOutCh->sfbEnFacLd[sfb+sfbGrp]; 791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* pe without reduction */ 797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FDKaacEnc_calcPe(psyOutChannel, qcOutChannel, peData, nChannels); 798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/***************************************************************************** 803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfunctionname: FDKaacEnc_FDKaacEnc_calcPeNoAH 804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdescription: sum the pe data only for bands where avoid hole is inactive 805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org*****************************************************************************/ 806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void FDKaacEnc_FDKaacEnc_calcPeNoAH(INT *pe, 807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT *constPart, 808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT *nActiveLines, 809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PE_DATA *peData, 810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UCHAR ahFlag[(2)][MAX_GROUPED_SFB], 811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PSY_OUT_CHANNEL* psyOutChannel[(2)], 812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const INT nChannels) 813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT ch, sfb,sfbGrp; 815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT pe_tmp = peData->offset; 817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT constPart_tmp = 0; 818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INT nActiveLines_tmp = 0; 819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(ch=0; ch<nChannels; ch++) { 820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch]; 821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup){ 822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { 823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(ahFlag[ch][sfbGrp+sfb] < AH_ACTIVE) { 824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pe_tmp += peChanData->sfbPe[sfbGrp+sfb]; 825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org constPart_tmp += peChanData->sfbConstPart[sfbGrp+sfb]; 826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nActiveLines_tmp += peChanData->sfbNActiveLines[sfbGrp+sfb]; 827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* correct scaled pe and constPart values */ 832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *pe = pe_tmp >> PE_CONSTPART_SHIFT; 833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *constPart = constPart_tmp >> PE_CONSTPART_SHIFT; 834 835 *nActiveLines = nActiveLines_tmp; 836} 837 838 839/***************************************************************************** 840functionname: FDKaacEnc_reduceThresholdsCBR 841description: apply reduction formula 842*****************************************************************************/ 843static const FIXP_DBL limitThrReducedLdData = (FIXP_DBL)0x00008000; /*FL2FXCONST_DBL(FDKpow(2.0,-LD_DATA_SCALING/4.0));*/ 844 845static void FDKaacEnc_reduceThresholdsCBR(QC_OUT_CHANNEL* qcOutChannel[(2)], 846 PSY_OUT_CHANNEL* psyOutChannel[(2)], 847 UCHAR ahFlag[(2)][MAX_GROUPED_SFB], 848 FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], 849 const INT nChannels, 850 const FIXP_DBL redVal, 851 const SCHAR redValScaling) 852{ 853 INT ch, sfb, sfbGrp; 854 FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData; 855 FIXP_DBL sfbThrExp; 856 857 for(ch=0; ch<nChannels; ch++) { 858 QC_OUT_CHANNEL *qcOutChan = qcOutChannel[ch]; 859 for(sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+= psyOutChannel[ch]->sfbPerGroup){ 860 for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { 861 sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb]; 862 sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp+sfb]; 863 sfbThrExp = thrExp[ch][sfbGrp+sfb]; 864 if ((sfbEnLdData > sfbThrLdData) && (ahFlag[ch][sfbGrp+sfb] != AH_ACTIVE)) { 865 866 /* threshold reduction formula: 867 float tmp = thrExp[ch][sfb]+redVal; 868 tmp *= tmp; 869 sfbThrReduced = tmp*tmp; 870 */ 871 int minScale = fixMin(CountLeadingBits(sfbThrExp), CountLeadingBits(redVal) - (DFRACT_BITS-1-redValScaling) )-1; 872 873 /* 4*log( sfbThrExp + redVal ) */ 874 sfbThrReducedLdData = CalcLdData(fAbs(scaleValue(sfbThrExp, minScale) + scaleValue(redVal,(DFRACT_BITS-1-redValScaling)+minScale))) 875 - (FIXP_DBL)(minScale<<(DFRACT_BITS-1-LD_DATA_SHIFT)); 876 sfbThrReducedLdData <<= 2; 877 878 /* avoid holes */ 879 if ( ((sfbThrReducedLdData - sfbEnLdData) > qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] ) 880 && (ahFlag[ch][sfbGrp+sfb] != NO_AH) ) 881 { 882 if (qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] > (FL2FXCONST_DBL(-1.0f) - sfbEnLdData) ){ 883 sfbThrReducedLdData = fixMax((qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] + sfbEnLdData), sfbThrLdData); 884 } 885 else sfbThrReducedLdData = sfbThrLdData; 886 ahFlag[ch][sfbGrp+sfb] = AH_ACTIVE; 887 } 888 889 /* minimum of 29 dB Ratio for Thresholds */ 890 if ((sfbEnLdData+(FIXP_DBL)MAXVAL_DBL) > FL2FXCONST_DBL(9.6336206/LD_DATA_SCALING)){ 891 sfbThrReducedLdData = fixMax(sfbThrReducedLdData, (sfbEnLdData - FL2FXCONST_DBL(9.6336206/LD_DATA_SCALING))); 892 } 893 894 qcOutChan->sfbThresholdLdData[sfbGrp+sfb] = sfbThrReducedLdData; 895 } 896 } 897 } 898 } 899} 900 901/* similar to prepareSfbPe1() */ 902static FIXP_DBL FDKaacEnc_calcChaosMeasure(PSY_OUT_CHANNEL *psyOutChannel, 903 const FIXP_DBL *sfbFormFactorLdData) 904{ 905 #define SCALE_FORM_FAC (4) /* (SCALE_FORM_FAC+FORM_FAC_SHIFT) >= ld(FRAME_LENGTH)*/ 906 #define SCALE_NRGS (8) 907 #define SCALE_NLINES (16) 908 #define SCALE_NRGS_SQRT4 (2) /* 0.25 * SCALE_NRGS */ 909 #define SCALE_NLINES_P34 (12) /* 0.75 * SCALE_NLINES */ 910 911 INT sfbGrp, sfb; 912 FIXP_DBL chaosMeasure; 913 INT frameNLines = 0; 914 FIXP_DBL frameFormFactor = FL2FXCONST_DBL(0.f); 915 FIXP_DBL frameEnergy = FL2FXCONST_DBL(0.f); 916 917 for (sfbGrp=0; sfbGrp<psyOutChannel->sfbCnt; sfbGrp+=psyOutChannel->sfbPerGroup) { 918 for (sfb=0; sfb<psyOutChannel->maxSfbPerGroup; sfb++){ 919 if (psyOutChannel->sfbEnergyLdData[sfbGrp+sfb] > psyOutChannel->sfbThresholdLdData[sfbGrp+sfb]) { 920 frameFormFactor += (CalcInvLdData(sfbFormFactorLdData[sfbGrp+sfb])>>SCALE_FORM_FAC); 921 frameNLines += (psyOutChannel->sfbOffsets[sfbGrp+sfb+1] - psyOutChannel->sfbOffsets[sfbGrp+sfb]); 922 frameEnergy += (psyOutChannel->sfbEnergy[sfbGrp+sfb]>>SCALE_NRGS); 923 } 924 } 925 } 926 927 if(frameNLines > 0){ 928 929 /* frameNActiveLines = frameFormFactor*2^FORM_FAC_SHIFT * ((frameEnergy *2^SCALE_NRGS)/frameNLines)^-0.25 930 chaosMeasure = frameNActiveLines / frameNLines */ 931 chaosMeasure = 932 CalcInvLdData( (((CalcLdData(frameFormFactor)>>1) - 933 (CalcLdData(frameEnergy)>>(2+1))) - 934 (fMultDiv2(FL2FXCONST_DBL(0.75f),CalcLdData((FIXP_DBL)frameNLines<<(DFRACT_BITS-1-SCALE_NLINES))) - 935 (((FIXP_DBL)(SCALE_FORM_FAC-SCALE_NRGS_SQRT4+FORM_FAC_SHIFT-(SCALE_NLINES_P34))<<(DFRACT_BITS-1-LD_DATA_SHIFT))>>1)) 936 )<<1 ); 937 } else { 938 939 /* assuming total chaos, if no sfb is above thresholds */ 940 chaosMeasure = FL2FXCONST_DBL(1.f); 941 } 942 943 return chaosMeasure; 944} 945 946/* apply reduction formula for VBR-mode */ 947static void FDKaacEnc_reduceThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], 948 PSY_OUT_CHANNEL* psyOutChannel[(2)], 949 UCHAR ahFlag[(2)][MAX_GROUPED_SFB], 950 FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], 951 const INT nChannels, 952 const FIXP_DBL vbrQualFactor, 953 FIXP_DBL* chaosMeasureOld) 954{ 955 INT ch, sfbGrp, sfb; 956 FIXP_DBL chGroupEnergy[TRANS_FAC][2];/*energy for each group and channel*/ 957 FIXP_DBL chChaosMeasure[2]; 958 FIXP_DBL frameEnergy = FL2FXCONST_DBL(1e-10f); 959 FIXP_DBL chaosMeasure = FL2FXCONST_DBL(0.f); 960 FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrExp; 961 FIXP_DBL sfbThrReducedLdData; 962 FIXP_DBL chaosMeasureAvg; 963 INT groupCnt; /* loop counter */ 964 FIXP_DBL redVal[TRANS_FAC]; /* reduction values; in short-block case one redVal for each group */ 965 QC_OUT_CHANNEL *qcOutChan = NULL; 966 PSY_OUT_CHANNEL *psyOutChan = NULL; 967 968#define SCALE_GROUP_ENERGY (8) 969 970#define CONST_CHAOS_MEAS_AVG_FAC_0 (FL2FXCONST_DBL(0.25f)) 971#define CONST_CHAOS_MEAS_AVG_FAC_1 (FL2FXCONST_DBL(1.f-0.25f)) 972 973#define MIN_LDTHRESH (FL2FXCONST_DBL(-0.515625f)) 974 975 976 for(ch=0; ch<nChannels; ch++){ 977 qcOutChan = qcOutChannel[ch]; 978 psyOutChan = psyOutChannel[ch]; 979 980 /* adding up energy for each channel and each group separately */ 981 FIXP_DBL chEnergy = FL2FXCONST_DBL(0.f); 982 groupCnt=0; 983 984 for (sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup, groupCnt++) { 985 chGroupEnergy[groupCnt][ch] = FL2FXCONST_DBL(0.f); 986 for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++){ 987 chGroupEnergy[groupCnt][ch] += (psyOutChan->sfbEnergy[sfbGrp+sfb]>>SCALE_GROUP_ENERGY); 988 } 989 chEnergy += chGroupEnergy[groupCnt][ch]; 990 } 991 frameEnergy += chEnergy; 992 993 /* chaosMeasure */ 994 if (psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) { 995 chChaosMeasure[ch] = FL2FXCONST_DBL(0.5f); /* assume a constant chaos measure of 0.5f for short blocks */ 996 } else { 997 chChaosMeasure[ch] = FDKaacEnc_calcChaosMeasure(psyOutChannel[ch], qcOutChannel[ch]->sfbFormFactorLdData); 998 } 999 chaosMeasure += fMult(chChaosMeasure[ch], chEnergy); 1000 } 1001 1002 if(frameEnergy > chaosMeasure) { 1003 INT scale = CntLeadingZeros(frameEnergy) - 1; 1004 FIXP_DBL num = chaosMeasure<<scale; 1005 FIXP_DBL denum = frameEnergy<<scale; 1006 chaosMeasure = schur_div(num,denum,16); 1007 } 1008 else { 1009 chaosMeasure = FL2FXCONST_DBL(1.f); 1010 } 1011 1012 chaosMeasureAvg = fMult(CONST_CHAOS_MEAS_AVG_FAC_0, chaosMeasure) + 1013 fMult(CONST_CHAOS_MEAS_AVG_FAC_1, *chaosMeasureOld); /* averaging chaos measure */ 1014 *chaosMeasureOld = chaosMeasure = (fixMin(chaosMeasure, chaosMeasureAvg)); /* use min-value, safe for next frame */ 1015 1016 /* characteristic curve 1017 chaosMeasure = 0.2f + 0.7f/0.3f * (chaosMeasure - 0.2f); 1018 chaosMeasure = fixMin(1.0f, fixMax(0.1f, chaosMeasure)); 1019 constants scaled by 4.f 1020 */ 1021 chaosMeasure = ((FL2FXCONST_DBL(0.2f)>>2) + fMult(FL2FXCONST_DBL(0.7f/(4.f*0.3f)), (chaosMeasure - FL2FXCONST_DBL(0.2f)))); 1022 chaosMeasure = (fixMin((FIXP_DBL)(FL2FXCONST_DBL(1.0f)>>2), fixMax((FIXP_DBL)(FL2FXCONST_DBL(0.1f)>>2), chaosMeasure)))<<2; 1023 1024 /* calculation of reduction value */ 1025 if (psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW){ /* short-blocks */ 1026 FDK_ASSERT(TRANS_FAC==8); 1027 #define WIN_TYPE_SCALE (3) 1028 1029 INT sfbGrp, groupCnt=0; 1030 for (sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup,groupCnt++) { 1031 1032 FIXP_DBL groupEnergy = FL2FXCONST_DBL(0.f); 1033 1034 for(ch=0;ch<nChannels;ch++){ 1035 groupEnergy += chGroupEnergy[groupCnt][ch]; /* adding up the channels groupEnergy */ 1036 } 1037 1038 FDK_ASSERT(psyOutChannel[0]->groupLen[groupCnt]<=INV_INT_TAB_SIZE); 1039 groupEnergy = fMult(groupEnergy,invInt[psyOutChannel[0]->groupLen[groupCnt]]); /* correction of group energy */ 1040 groupEnergy = fixMin(groupEnergy, frameEnergy>>WIN_TYPE_SCALE); /* do not allow an higher redVal as calculated framewise */ 1041 1042 groupEnergy>>=2; /* 2*WIN_TYPE_SCALE = 6 => 6+2 = 8 ==> 8/4 = int number */ 1043 1044 redVal[groupCnt] = fMult(fMult(vbrQualFactor,chaosMeasure), 1045 CalcInvLdData(CalcLdData(groupEnergy)>>2) ) 1046 << (int)( ( 2 + (2*WIN_TYPE_SCALE) + SCALE_GROUP_ENERGY )>>2 ) ; 1047 1048 } 1049 } else { /* long-block */ 1050 1051 redVal[0] = fMult( fMult(vbrQualFactor,chaosMeasure), 1052 CalcInvLdData(CalcLdData(frameEnergy)>>2) ) 1053 << (int)( SCALE_GROUP_ENERGY>>2 ) ; 1054 } 1055 1056 for(ch=0; ch<nChannels; ch++) { 1057 qcOutChan = qcOutChannel[ch]; 1058 psyOutChan = psyOutChannel[ch]; 1059 1060 for (sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) { 1061 for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++){ 1062 1063 sfbEnLdData = (qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb]); 1064 sfbThrLdData = (qcOutChan->sfbThresholdLdData[sfbGrp+sfb]); 1065 sfbThrExp = thrExp[ch][sfbGrp+sfb]; 1066 1067 if ( (sfbThrLdData>=MIN_LDTHRESH) && (sfbEnLdData > sfbThrLdData) && (ahFlag[ch][sfbGrp+sfb] != AH_ACTIVE)) { 1068 1069 /* Short-Window */ 1070 if (psyOutChannel[ch]->lastWindowSequence == SHORT_WINDOW) { 1071 const int groupNumber = (int) sfb/psyOutChan->sfbPerGroup; 1072 1073 FDK_ASSERT(INV_SQRT4_TAB_SIZE>psyOutChan->groupLen[groupNumber]); 1074 1075 sfbThrExp = fMult(sfbThrExp, fMult( FL2FXCONST_DBL(2.82f/4.f), invSqrt4[psyOutChan->groupLen[groupNumber]]))<<2 ; 1076 1077 if ( sfbThrExp <= (limitThrReducedLdData-redVal[groupNumber]) ) { 1078 sfbThrReducedLdData = FL2FXCONST_DBL(-1.0f); 1079 } 1080 else { 1081 if ((FIXP_DBL)redVal[groupNumber] >= FL2FXCONST_DBL(1.0f)-sfbThrExp) 1082 sfbThrReducedLdData = FL2FXCONST_DBL(0.0f); 1083 else { 1084 /* threshold reduction formula */ 1085 sfbThrReducedLdData = CalcLdData(sfbThrExp + redVal[groupNumber]); 1086 sfbThrReducedLdData <<= 2; 1087 } 1088 } 1089 sfbThrReducedLdData += ( CalcLdInt(psyOutChan->groupLen[groupNumber]) - 1090 ((FIXP_DBL)6<<(DFRACT_BITS-1-LD_DATA_SHIFT)) ); 1091 } 1092 1093 /* Long-Window */ 1094 else { 1095 if ((FIXP_DBL)redVal[0] >= FL2FXCONST_DBL(1.0f)-sfbThrExp) { 1096 sfbThrReducedLdData = FL2FXCONST_DBL(0.0f); 1097 } 1098 else { 1099 /* threshold reduction formula */ 1100 sfbThrReducedLdData = CalcLdData(sfbThrExp + redVal[0]); 1101 sfbThrReducedLdData <<= 2; 1102 } 1103 } 1104 1105 /* avoid holes */ 1106 if ( ((sfbThrReducedLdData - sfbEnLdData) > qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] ) 1107 && (ahFlag[ch][sfbGrp+sfb] != NO_AH) ) 1108 { 1109 if (qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] > (FL2FXCONST_DBL(-1.0f) - sfbEnLdData) ){ 1110 sfbThrReducedLdData = fixMax((qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] + sfbEnLdData), sfbThrLdData); 1111 } 1112 else sfbThrReducedLdData = sfbThrLdData; 1113 ahFlag[ch][sfbGrp+sfb] = AH_ACTIVE; 1114 } 1115 1116 if (sfbThrReducedLdData<FL2FXCONST_DBL(-0.5f)) 1117 sfbThrReducedLdData = FL2FXCONST_DBL(-1.f); 1118 1119 /* minimum of 29 dB Ratio for Thresholds */ 1120 if ((sfbEnLdData+FL2FXCONST_DBL(1.0f)) > FL2FXCONST_DBL(9.6336206/LD_DATA_SCALING)){ 1121 sfbThrReducedLdData = fixMax(sfbThrReducedLdData, sfbEnLdData - FL2FXCONST_DBL(9.6336206/LD_DATA_SCALING)); 1122 } 1123 1124 sfbThrReducedLdData = fixMax(MIN_LDTHRESH,sfbThrReducedLdData); 1125 1126 qcOutChan->sfbThresholdLdData[sfbGrp+sfb] = sfbThrReducedLdData; 1127 } 1128 } 1129 } 1130 } 1131} 1132 1133/***************************************************************************** 1134functionname: FDKaacEnc_correctThresh 1135description: if pe difference deltaPe between desired pe and real pe is small enough, 1136the difference can be distributed among the scale factor bands. 1137New thresholds can be derived from this pe-difference 1138*****************************************************************************/ 1139static void FDKaacEnc_correctThresh(CHANNEL_MAPPING* cm, 1140 QC_OUT_ELEMENT* qcElement[(8)], 1141 PSY_OUT_ELEMENT* psyOutElement[(8)], 1142 UCHAR ahFlag[(8)][(2)][MAX_GROUPED_SFB], 1143 FIXP_DBL thrExp[(8)][(2)][MAX_GROUPED_SFB], 1144 const FIXP_DBL redVal[(8)], 1145 const SCHAR redValScaling[(8)], 1146 const INT deltaPe, 1147 const INT processElements, 1148 const INT elementOffset) 1149{ 1150 INT ch, sfb, sfbGrp; 1151 QC_OUT_CHANNEL *qcOutChan; 1152 PSY_OUT_CHANNEL *psyOutChan; 1153 PE_CHANNEL_DATA *peChanData; 1154 FIXP_DBL thrFactorLdData; 1155 FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData; 1156 FIXP_DBL *sfbPeFactorsLdData[(8)][(2)]; 1157 FIXP_DBL sfbNActiveLinesLdData[(8)][(2)][MAX_GROUPED_SFB]; 1158 INT normFactorInt; 1159 FIXP_DBL normFactorLdData; 1160 1161 INT nElements = elementOffset+processElements; 1162 INT elementId; 1163 1164 /* scratch is empty; use temporal memory from quantSpec in QC_OUT_CHANNEL */ 1165 for(elementId=elementOffset;elementId<nElements;elementId++) { 1166 for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { 1167 SHORT* ptr = qcElement[elementId]->qcOutChannel[ch]->quantSpec; 1168 sfbPeFactorsLdData[elementId][ch] = (FIXP_DBL*)ptr; 1169 } 1170 } 1171 1172 /* for each sfb calc relative factors for pe changes */ 1173 normFactorInt = 0; 1174 1175 for(elementId=elementOffset;elementId<nElements;elementId++) { 1176 if (cm->elInfo[elementId].elType != ID_DSE) { 1177 1178 for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { 1179 1180 qcOutChan = qcElement[elementId]->qcOutChannel[ch]; 1181 psyOutChan = psyOutElement[elementId]->psyOutChannel[ch]; 1182 peChanData = &qcElement[elementId]->peData.peChannelData[ch]; 1183 1184 for(sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; sfbGrp+= psyOutChan->sfbPerGroup){ 1185 for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) { 1186 1187 if ( peChanData->sfbNActiveLines[sfbGrp+sfb] == 0 ) { 1188 sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] = FL2FXCONST_DBL(-1.0f); 1189 } 1190 else { 1191 /* Both CalcLdInt and CalcLdData can be used! 1192 * No offset has to be subtracted, because sfbNActiveLinesLdData 1193 * is shorted while thrFactor calculation */ 1194 sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] = CalcLdInt(peChanData->sfbNActiveLines[sfbGrp+sfb]); 1195 } 1196 if ( ((ahFlag[elementId][ch][sfbGrp+sfb] < AH_ACTIVE) || (deltaPe > 0)) && 1197 peChanData->sfbNActiveLines[sfbGrp+sfb] != 0 ) 1198 { 1199 if (thrExp[elementId][ch][sfbGrp+sfb] > -redVal[elementId]) { 1200 1201 /* sfbPeFactors[ch][sfbGrp+sfb] = peChanData->sfbNActiveLines[sfbGrp+sfb] / 1202 (thrExp[elementId][ch][sfbGrp+sfb] + redVal[elementId]); */ 1203 1204 int minScale = fixMin(CountLeadingBits(thrExp[elementId][ch][sfbGrp+sfb]), CountLeadingBits(redVal[elementId]) - (DFRACT_BITS-1-redValScaling[elementId]) ) - 1; 1205 1206 /* sumld = ld64( sfbThrExp + redVal ) */ 1207 FIXP_DBL sumLd = CalcLdData(scaleValue(thrExp[elementId][ch][sfbGrp+sfb], minScale) + scaleValue(redVal[elementId], (DFRACT_BITS-1-redValScaling[elementId])+minScale)) 1208 - (FIXP_DBL)(minScale<<(DFRACT_BITS-1-LD_DATA_SHIFT)); 1209 1210 if (sumLd < FL2FXCONST_DBL(0.f)) { 1211 sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] - sumLd; 1212 } 1213 else { 1214 if ( sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] > (FL2FXCONST_DBL(-1.f) + sumLd) ) { 1215 sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] - sumLd; 1216 } 1217 else { 1218 sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb]; 1219 } 1220 } 1221 1222 normFactorInt += (INT)CalcInvLdData(sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb]); 1223 } 1224 else sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = FL2FXCONST_DBL(1.0f); 1225 } 1226 else sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = FL2FXCONST_DBL(-1.0f); 1227 } 1228 } 1229 } 1230 } 1231 } 1232 1233 /* normFactorLdData = ld64(deltaPe/normFactorInt) */ 1234 normFactorLdData = CalcLdData((FIXP_DBL)((deltaPe<0) ? (-deltaPe) : (deltaPe))) - CalcLdData((FIXP_DBL)normFactorInt); 1235 1236 /* distribute the pe difference to the scalefactors 1237 and calculate the according thresholds */ 1238 for(elementId=elementOffset;elementId<nElements;elementId++) { 1239 if (cm->elInfo[elementId].elType != ID_DSE) { 1240 1241 for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { 1242 qcOutChan = qcElement[elementId]->qcOutChannel[ch]; 1243 psyOutChan = psyOutElement[elementId]->psyOutChannel[ch]; 1244 peChanData = &qcElement[elementId]->peData.peChannelData[ch]; 1245 1246 for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){ 1247 for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) { 1248 1249 if (peChanData->sfbNActiveLines[sfbGrp+sfb] > 0) { 1250 1251 /* pe difference for this sfb */ 1252 if ( (sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb]==FL2FXCONST_DBL(-1.0f)) || 1253 (deltaPe==0) ) 1254 { 1255 thrFactorLdData = FL2FXCONST_DBL(0.f); 1256 } 1257 else { 1258 /* new threshold */ 1259 FIXP_DBL tmp = CalcInvLdData(sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] + normFactorLdData - sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] - FL2FXCONST_DBL((float)LD_DATA_SHIFT/LD_DATA_SCALING)); 1260 1261 /* limit thrFactor to 60dB */ 1262 tmp = (deltaPe<0) ? tmp : (-tmp); 1263 thrFactorLdData = FDKmin(tmp, FL2FXCONST_DBL(20.f/LD_DATA_SCALING)); 1264 } 1265 1266 /* new threshold */ 1267 sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp+sfb]; 1268 sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb]; 1269 1270 if (thrFactorLdData < FL2FXCONST_DBL(0.f)) { 1271 if( sfbThrLdData > (FL2FXCONST_DBL(-1.f)-thrFactorLdData) ) { 1272 sfbThrReducedLdData = sfbThrLdData + thrFactorLdData; 1273 } 1274 else { 1275 sfbThrReducedLdData = FL2FXCONST_DBL(-1.f); 1276 } 1277 } 1278 else{ 1279 sfbThrReducedLdData = sfbThrLdData + thrFactorLdData; 1280 } 1281 1282 /* avoid hole */ 1283 if ( (sfbThrReducedLdData - sfbEnLdData > qcOutChan->sfbMinSnrLdData[sfbGrp+sfb]) && 1284 (ahFlag[elementId][ch][sfbGrp+sfb] == AH_INACTIVE) ) 1285 { 1286 /* sfbThrReduced = max(psyOutChan[ch]->sfbMinSnr[i] * sfbEn, sfbThr); */ 1287 if ( sfbEnLdData > (sfbThrLdData-qcOutChan->sfbMinSnrLdData[sfbGrp+sfb]) ) { 1288 sfbThrReducedLdData = qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] + sfbEnLdData; 1289 } 1290 else { 1291 sfbThrReducedLdData = sfbThrLdData; 1292 } 1293 ahFlag[elementId][ch][sfbGrp+sfb] = AH_ACTIVE; 1294 } 1295 1296 qcOutChan->sfbThresholdLdData[sfbGrp+sfb] = sfbThrReducedLdData; 1297 } 1298 } 1299 } 1300 } 1301 } 1302 } 1303} 1304 1305/***************************************************************************** 1306 functionname: FDKaacEnc_reduceMinSnr 1307 description: if the desired pe can not be reached, reduce pe by 1308 reducing minSnr 1309*****************************************************************************/ 1310void FDKaacEnc_reduceMinSnr(CHANNEL_MAPPING* cm, 1311 QC_OUT_ELEMENT* qcElement[(8)], 1312 PSY_OUT_ELEMENT* psyOutElement[(8)], 1313 UCHAR ahFlag[(8)][(2)][MAX_GROUPED_SFB], 1314 const INT desiredPe, 1315 INT* redPeGlobal, 1316 const INT processElements, 1317 const INT elementOffset) 1318 1319{ 1320 INT elementId; 1321 INT nElements = elementOffset+processElements; 1322 1323 INT newGlobalPe = *redPeGlobal; 1324 1325 for(elementId=elementOffset;elementId<nElements;elementId++) { 1326 if (cm->elInfo[elementId].elType != ID_DSE) { 1327 INT ch; 1328 INT maxSfbPerGroup[2]; 1329 INT sfbCnt[2]; 1330 INT sfbPerGroup[2]; 1331 1332 for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { 1333 maxSfbPerGroup[ch] = psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup-1; 1334 sfbCnt[ch] = psyOutElement[elementId]->psyOutChannel[ch]->sfbCnt; 1335 sfbPerGroup[ch] = psyOutElement[elementId]->psyOutChannel[ch]->sfbPerGroup; 1336 } 1337 1338 PE_DATA *peData = &qcElement[elementId]->peData; 1339 1340 do 1341 { 1342 for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { 1343 1344 INT sfb, sfbGrp; 1345 QC_OUT_CHANNEL *qcOutChan = qcElement[elementId]->qcOutChannel[ch]; 1346 INT noReduction = 1; 1347 1348 if (maxSfbPerGroup[ch]>=0) { /* sfb in next channel */ 1349 INT deltaPe = 0; 1350 sfb = maxSfbPerGroup[ch]--; 1351 noReduction = 0; 1352 1353 for (sfbGrp = 0; sfbGrp < sfbCnt[ch]; sfbGrp += sfbPerGroup[ch]) { 1354 1355 if (ahFlag[elementId][ch][sfbGrp+sfb] != NO_AH && 1356 qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] < SnrLdFac) 1357 { 1358 /* increase threshold to new minSnr of 1dB */ 1359 qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] = SnrLdFac; 1360 1361 /* sfbThrReduced = max(psyOutChan[ch]->sfbMinSnr[i] * sfbEn, sfbThr); */ 1362 if ( qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb] >= qcOutChan->sfbThresholdLdData[sfbGrp+sfb] - qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] ) { 1363 1364 qcOutChan->sfbThresholdLdData[sfbGrp+sfb] = qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb] + qcOutChan->sfbMinSnrLdData[sfbGrp+sfb]; 1365 1366 /* calc new pe */ 1367 /* C2 + C3*ld(1/0.8) = 1.5 */ 1368 deltaPe -= (peData->peChannelData[ch].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT); 1369 1370 /* sfbPe = 1.5 * sfbNLines */ 1371 peData->peChannelData[ch].sfbPe[sfbGrp+sfb] = (3*peData->peChannelData[ch].sfbNLines[sfbGrp+sfb]) << (PE_CONSTPART_SHIFT-1); 1372 deltaPe += (peData->peChannelData[ch].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT); 1373 } 1374 } 1375 1376 } /* sfbGrp loop */ 1377 1378 peData->pe += deltaPe; 1379 peData->peChannelData[ch].pe += deltaPe; 1380 newGlobalPe += deltaPe; 1381 1382 /* stop if enough has been saved */ 1383 if (peData->pe <= desiredPe) { 1384 goto bail; 1385 } 1386 1387 } /* sfb > 0 */ 1388 1389 if ( (ch==(cm->elInfo[elementId].nChannelsInEl-1)) && noReduction ) { 1390 goto bail; 1391 } 1392 1393 } /* ch loop */ 1394 1395 } while ( peData->pe > desiredPe); 1396 1397 } /* != ID_DSE */ 1398 } /* element loop */ 1399 1400 1401bail: 1402 /* update global PE */ 1403 *redPeGlobal = newGlobalPe; 1404} 1405 1406 1407/***************************************************************************** 1408 functionname: FDKaacEnc_allowMoreHoles 1409 description: if the desired pe can not be reached, some more scalefactor 1410 bands have to be quantized to zero 1411*****************************************************************************/ 1412static void FDKaacEnc_allowMoreHoles(CHANNEL_MAPPING* cm, 1413 QC_OUT_ELEMENT* qcElement[(8)], 1414 PSY_OUT_ELEMENT* psyOutElement[(8)], 1415 ATS_ELEMENT* AdjThrStateElement[(8)], 1416 UCHAR ahFlag[(8)][(2)][MAX_GROUPED_SFB], 1417 const INT desiredPe, 1418 const INT currentPe, 1419 const int processElements, 1420 const int elementOffset) 1421{ 1422 INT elementId; 1423 INT nElements = elementOffset+processElements; 1424 INT actPe = currentPe; 1425 1426 if (actPe <= desiredPe) { 1427 return; /* nothing to do */ 1428 } 1429 1430 for (elementId = elementOffset;elementId<nElements;elementId++) { 1431 if (cm->elInfo[elementId].elType != ID_DSE) { 1432 1433 INT ch, sfb, sfbGrp; 1434 1435 PE_DATA *peData = &qcElement[elementId]->peData; 1436 const INT nChannels = cm->elInfo[elementId].nChannelsInEl; 1437 1438 QC_OUT_CHANNEL* qcOutChannel[(2)] = {NULL}; 1439 PSY_OUT_CHANNEL* psyOutChannel[(2)] = {NULL}; 1440 1441 for (ch=0; ch<nChannels; ch++) { 1442 1443 /* init pointers */ 1444 qcOutChannel[ch] = qcElement[elementId]->qcOutChannel[ch]; 1445 psyOutChannel[ch] = psyOutElement[elementId]->psyOutChannel[ch]; 1446 1447 for(sfbGrp=0; sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+= psyOutChannel[ch]->sfbPerGroup) { 1448 for (sfb=psyOutChannel[ch]->maxSfbPerGroup; sfb<psyOutChannel[ch]->sfbPerGroup; sfb++) { 1449 peData->peChannelData[ch].sfbPe[sfbGrp+sfb] = 0; 1450 } 1451 } 1452 } 1453 1454 /* for MS allow hole in the channel with less energy */ 1455 if ( nChannels==2 && psyOutChannel[0]->lastWindowSequence==psyOutChannel[1]->lastWindowSequence ) { 1456 1457 for (sfb=0; sfb<psyOutChannel[0]->maxSfbPerGroup; sfb++) { 1458 for(sfbGrp=0; sfbGrp < psyOutChannel[0]->sfbCnt; sfbGrp+=psyOutChannel[0]->sfbPerGroup) { 1459 if (psyOutElement[elementId]->toolsInfo.msMask[sfbGrp+sfb]) { 1460 FIXP_DBL EnergyLd_L = qcOutChannel[0]->sfbWeightedEnergyLdData[sfbGrp+sfb]; 1461 FIXP_DBL EnergyLd_R = qcOutChannel[1]->sfbWeightedEnergyLdData[sfbGrp+sfb]; 1462 1463 /* allow hole in side channel ? */ 1464 if ( (ahFlag[elementId][1][sfbGrp+sfb] != NO_AH) && 1465 (((FL2FXCONST_DBL(-0.02065512648f)>>1) + (qcOutChannel[0]->sfbMinSnrLdData[sfbGrp+sfb]>>1)) 1466 > ((EnergyLd_R>>1) - (EnergyLd_L>>1))) ) 1467 { 1468 ahFlag[elementId][1][sfbGrp+sfb] = NO_AH; 1469 qcOutChannel[1]->sfbThresholdLdData[sfbGrp+sfb] = FL2FXCONST_DBL(0.015625f) + EnergyLd_R; 1470 actPe -= peData->peChannelData[1].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT; 1471 } 1472 /* allow hole in mid channel ? */ 1473 else if ( (ahFlag[elementId][0][sfbGrp+sfb] != NO_AH) && 1474 (((FL2FXCONST_DBL(-0.02065512648f)>>1) + (qcOutChannel[1]->sfbMinSnrLdData[sfbGrp+sfb]>>1)) 1475 > ((EnergyLd_L>>1) - (EnergyLd_R>>1))) ) 1476 { 1477 ahFlag[elementId][0][sfbGrp+sfb] = NO_AH; 1478 qcOutChannel[0]->sfbThresholdLdData[sfbGrp+sfb] = FL2FXCONST_DBL(0.015625f) + EnergyLd_L; 1479 actPe -= peData->peChannelData[0].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT; 1480 } /* if (ahFlag) */ 1481 } /* if MS */ 1482 } /* sfbGrp */ 1483 if (actPe <= desiredPe) { 1484 return; /* stop if enough has been saved */ 1485 } 1486 } /* sfb */ 1487 } /* MS possible ? */ 1488 1489 /* more holes necessary? subsequently erase bands 1490 starting with low energies */ 1491 INT startSfb[2]; 1492 FIXP_DBL avgEnLD64,minEnLD64; 1493 INT ahCnt; 1494 FIXP_DBL ahCntLD64; 1495 INT enIdx; 1496 FIXP_DBL enLD64[4]; 1497 FIXP_DBL avgEn; 1498 1499 /* do not go below startSfb */ 1500 for (ch=0; ch<nChannels; ch++) { 1501 if (psyOutChannel[ch]->lastWindowSequence != SHORT_WINDOW) 1502 startSfb[ch] = AdjThrStateElement[elementId]->ahParam.startSfbL; 1503 else 1504 startSfb[ch] = AdjThrStateElement[elementId]->ahParam.startSfbS; 1505 } 1506 1507 /* calc avg and min energies of bands that avoid holes */ 1508 avgEn = FL2FXCONST_DBL(0.0f); 1509 minEnLD64 = FL2FXCONST_DBL(0.0f); 1510 ahCnt = 0; 1511 1512 for (ch=0; ch<nChannels; ch++) { 1513 1514 sfbGrp=0; 1515 sfb=startSfb[ch]; 1516 1517 do { 1518 for (; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { 1519 if ((ahFlag[elementId][ch][sfbGrp+sfb]!=NO_AH) && 1520 (qcOutChannel[ch]->sfbWeightedEnergyLdData[sfbGrp+sfb] > qcOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb])){ 1521 minEnLD64 = fixMin(minEnLD64,qcOutChannel[ch]->sfbEnergyLdData[sfbGrp+sfb]); 1522 avgEn += qcOutChannel[ch]->sfbEnergy[sfbGrp+sfb] >> 6; 1523 ahCnt++; 1524 } 1525 } 1526 1527 sfbGrp += psyOutChannel[ch]->sfbPerGroup; 1528 sfb=0; 1529 1530 } while (sfbGrp < psyOutChannel[ch]->sfbCnt); 1531 } 1532 1533 if ( (avgEn == FL2FXCONST_DBL(0.0f)) || (ahCnt == 0) ) { 1534 avgEnLD64 = FL2FXCONST_DBL(0.0f); 1535 } 1536 else { 1537 avgEnLD64 = CalcLdData(avgEn); 1538 ahCntLD64 = CalcLdInt(ahCnt); 1539 avgEnLD64 = avgEnLD64 + FL2FXCONST_DBL(0.09375f) - ahCntLD64; /* compensate shift with 6 */ 1540 } 1541 1542 /* calc some energy borders between minEn and avgEn */ 1543 /* for (enIdx=0; enIdx<4; enIdx++) */ 1544 /* en[enIdx] = minEn * (float)FDKpow(avgEn/(minEn+FLT_MIN), (2*enIdx+1)/7.0f); */ 1545 enLD64[0] = minEnLD64 + fMult((avgEnLD64-minEnLD64),FL2FXCONST_DBL(0.14285714285f)); 1546 enLD64[1] = minEnLD64 + fMult((avgEnLD64-minEnLD64),FL2FXCONST_DBL(0.42857142857f)); 1547 enLD64[2] = minEnLD64 + fMult((avgEnLD64-minEnLD64),FL2FXCONST_DBL(0.71428571428f)); 1548 enLD64[3] = minEnLD64 + (avgEnLD64-minEnLD64); 1549 1550 for (enIdx=0; enIdx<4; enIdx++) { 1551 INT noReduction = 1; 1552 1553 INT maxSfbPerGroup[2]; 1554 INT sfbCnt[2]; 1555 INT sfbPerGroup[2]; 1556 1557 for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { 1558 maxSfbPerGroup[ch] = psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup-1; 1559 sfbCnt[ch] = psyOutElement[elementId]->psyOutChannel[ch]->sfbCnt; 1560 sfbPerGroup[ch] = psyOutElement[elementId]->psyOutChannel[ch]->sfbPerGroup; 1561 } 1562 1563 do { 1564 1565 noReduction = 1; 1566 1567 for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { 1568 1569 INT sfb, sfbGrp; 1570 1571 /* start with lowest energy border at highest sfb */ 1572 if (maxSfbPerGroup[ch]>=startSfb[ch]) { /* sfb in next channel */ 1573 sfb = maxSfbPerGroup[ch]--; 1574 noReduction = 0; 1575 1576 for (sfbGrp = 0; sfbGrp < sfbCnt[ch]; sfbGrp += sfbPerGroup[ch]) { 1577 /* sfb energy below border ? */ 1578 if (ahFlag[elementId][ch][sfbGrp+sfb] != NO_AH && qcOutChannel[ch]->sfbEnergyLdData[sfbGrp+sfb] < enLD64[enIdx]) { 1579 /* allow hole */ 1580 ahFlag[elementId][ch][sfbGrp+sfb] = NO_AH; 1581 qcOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb] = FL2FXCONST_DBL(0.015625f) + qcOutChannel[ch]->sfbWeightedEnergyLdData[sfbGrp+sfb]; 1582 actPe -= peData->peChannelData[ch].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT; 1583 } 1584 } /* sfbGrp */ 1585 1586 if (actPe <= desiredPe) { 1587 return; /* stop if enough has been saved */ 1588 } 1589 } /* sfb > 0 */ 1590 } /* ch loop */ 1591 1592 } while( (noReduction == 0) && (actPe > desiredPe) ); 1593 1594 if (actPe <= desiredPe) { 1595 return; /* stop if enough has been saved */ 1596 } 1597 1598 } /* enIdx loop */ 1599 1600 } /* EOF DSE-suppression */ 1601 } /* EOF for all elements... */ 1602 1603} 1604 1605/* reset avoid hole flags from AH_ACTIVE to AH_INACTIVE */ 1606static void FDKaacEnc_resetAHFlags( UCHAR ahFlag[(2)][MAX_GROUPED_SFB], 1607 const int nChannels, 1608 PSY_OUT_CHANNEL *psyOutChannel[(2)]) 1609{ 1610 int ch, sfb, sfbGrp; 1611 1612 for(ch=0; ch<nChannels; ch++) { 1613 for (sfbGrp=0; sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { 1614 for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { 1615 if ( ahFlag[ch][sfbGrp+sfb] == AH_ACTIVE) { 1616 ahFlag[ch][sfbGrp+sfb] = AH_INACTIVE; 1617 } 1618 } 1619 } 1620 } 1621} 1622 1623 1624static FIXP_DBL CalcRedValPower(FIXP_DBL num, 1625 FIXP_DBL denum, 1626 INT* scaling ) 1627{ 1628 FIXP_DBL value = FL2FXCONST_DBL(0.f); 1629 1630 if (num>=FL2FXCONST_DBL(0.f)) { 1631 value = fDivNorm( num, denum, scaling); 1632 } 1633 else { 1634 value = -fDivNorm( -num, denum, scaling); 1635 } 1636 value = f2Pow(value, *scaling, scaling); 1637 *scaling = DFRACT_BITS-1-*scaling; 1638 1639 return value; 1640} 1641 1642 1643/***************************************************************************** 1644functionname: FDKaacEnc_adaptThresholdsToPe 1645description: two guesses for the reduction value and one final correction of the thresholds 1646*****************************************************************************/ 1647static void FDKaacEnc_adaptThresholdsToPe(CHANNEL_MAPPING* cm, 1648 ATS_ELEMENT* AdjThrStateElement[(8)], 1649 QC_OUT_ELEMENT* qcElement[(8)], 1650 PSY_OUT_ELEMENT* psyOutElement[(8)], 1651 const INT desiredPe, 1652 const INT processElements, 1653 const INT elementOffset) 1654{ 1655 FIXP_DBL redValue[(8)]; 1656 SCHAR redValScaling[(8)]; 1657 UCHAR pAhFlag[(8)][(2)][MAX_GROUPED_SFB]; 1658 FIXP_DBL pThrExp[(8)][(2)][MAX_GROUPED_SFB]; 1659 int iter; 1660 1661 INT constPartGlobal, noRedPeGlobal, nActiveLinesGlobal, redPeGlobal; 1662 constPartGlobal = noRedPeGlobal = nActiveLinesGlobal = redPeGlobal = 0; 1663 1664 int elementId; 1665 1666 int nElements = elementOffset+processElements; 1667 if(nElements > cm->nElements) { 1668 nElements = cm->nElements; 1669 } 1670 1671 /* ------------------------------------------------------- */ 1672 /* Part I: Initialize data structures and variables... */ 1673 /* ------------------------------------------------------- */ 1674 for (elementId = elementOffset;elementId<nElements;elementId++) { 1675 if (cm->elInfo[elementId].elType != ID_DSE) { 1676 1677 INT nChannels = cm->elInfo[elementId].nChannelsInEl; 1678 PE_DATA *peData = &qcElement[elementId]->peData; 1679 1680 /* thresholds to the power of redExp */ 1681 FDKaacEnc_calcThreshExp(pThrExp[elementId], qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, nChannels); 1682 1683 /* lower the minSnr requirements for low energies compared to the average 1684 energy in this frame */ 1685 FDKaacEnc_adaptMinSnr(qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, &AdjThrStateElement[elementId]->minSnrAdaptParam, nChannels); 1686 1687 /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ 1688 FDKaacEnc_initAvoidHoleFlag(qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], &psyOutElement[elementId]->toolsInfo, nChannels, peData, &AdjThrStateElement[elementId]->ahParam); 1689 1690 /* sum up */ 1691 constPartGlobal += peData->constPart; 1692 noRedPeGlobal += peData->pe; 1693 nActiveLinesGlobal += fixMax((INT)peData->nActiveLines, 1); 1694 1695 } /* EOF DSE-suppression */ 1696 } /* EOF for all elements... */ 1697 1698 /* ----------------------------------------------------------------------- */ 1699 /* Part II: Calculate bit consumption of initial bit constraints setup */ 1700 /* ----------------------------------------------------------------------- */ 1701 for (elementId = elementOffset;elementId<nElements;elementId++) { 1702 if (cm->elInfo[elementId].elType != ID_DSE) { 1703 /* 1704 redVal = ( 2 ^ ( (constPartGlobal-desiredPe) / (invRedExp*nActiveLinesGlobal) ) 1705 - 2 ^ ( (constPartGlobal-noRedPeGlobal) / (invRedExp*nActiveLinesGlobal) ) ) 1706 */ 1707 1708 1709 INT nChannels = cm->elInfo[elementId].nChannelsInEl; 1710 PE_DATA *peData = &qcElement[elementId]->peData; 1711 1712 /* first guess of reduction value */ 1713 int scale0=0, scale1=0; 1714 FIXP_DBL tmp0 = CalcRedValPower( constPartGlobal-desiredPe, 4*nActiveLinesGlobal, &scale0 ); 1715 FIXP_DBL tmp1 = CalcRedValPower( constPartGlobal-noRedPeGlobal, 4*nActiveLinesGlobal, &scale1 ); 1716 1717 int scalMin = FDKmin(scale0, scale1)-1; 1718 1719 redValue[elementId] = scaleValue(tmp0,(scalMin-scale0)) - scaleValue(tmp1,(scalMin-scale1)); 1720 redValScaling[elementId] = scalMin; 1721 1722 /* reduce thresholds */ 1723 FDKaacEnc_reduceThresholdsCBR(qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], pThrExp[elementId], nChannels, redValue[elementId], redValScaling[elementId]); 1724 1725 /* pe after first guess */ 1726 FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, qcElement[elementId]->qcOutChannel, peData, nChannels); 1727 1728 redPeGlobal += peData->pe; 1729 } /* EOF DSE-suppression */ 1730 } /* EOF for all elements... */ 1731 1732 /* -------------------------------------------------- */ 1733 /* Part III: Iterate until bit constraints are met */ 1734 /* -------------------------------------------------- */ 1735 iter = 0; 1736 while ((fixp_abs(redPeGlobal - desiredPe) > fMultI(FL2FXCONST_DBL(0.05f),desiredPe)) && (iter < 1)) { 1737 1738 INT desiredPeNoAHGlobal; 1739 INT redPeNoAHGlobal = 0; 1740 INT constPartNoAHGlobal = 0; 1741 INT nActiveLinesNoAHGlobal = 0; 1742 1743 for (elementId = elementOffset;elementId<nElements;elementId++) { 1744 if (cm->elInfo[elementId].elType != ID_DSE) { 1745 1746 INT redPeNoAH, constPartNoAH, nActiveLinesNoAH; 1747 INT nChannels = cm->elInfo[elementId].nChannelsInEl; 1748 PE_DATA *peData = &qcElement[elementId]->peData; 1749 1750 /* pe for bands where avoid hole is inactive */ 1751 FDKaacEnc_FDKaacEnc_calcPeNoAH(&redPeNoAH, &constPartNoAH, &nActiveLinesNoAH, 1752 peData, pAhFlag[elementId], psyOutElement[elementId]->psyOutChannel, nChannels); 1753 1754 redPeNoAHGlobal += redPeNoAH; 1755 constPartNoAHGlobal += constPartNoAH; 1756 nActiveLinesNoAHGlobal += nActiveLinesNoAH; 1757 } /* EOF DSE-suppression */ 1758 } /* EOF for all elements... */ 1759 1760 /* Calculate new redVal ... */ 1761 if(desiredPe < redPeGlobal) { 1762 1763 /* new desired pe without bands where avoid hole is active */ 1764 desiredPeNoAHGlobal = desiredPe - (redPeGlobal - redPeNoAHGlobal); 1765 1766 /* limit desiredPeNoAH to positive values, as the PE can not become negative */ 1767 desiredPeNoAHGlobal = FDKmax(0,desiredPeNoAHGlobal); 1768 1769 /* second guess (only if there are bands left where avoid hole is inactive)*/ 1770 if (nActiveLinesNoAHGlobal > 0) { 1771 for (elementId = elementOffset;elementId<nElements;elementId++) { 1772 if (cm->elInfo[elementId].elType != ID_DSE) { 1773 /* 1774 redVal += ( 2 ^ ( (constPartNoAHGlobal-desiredPeNoAHGlobal) / (invRedExp*nActiveLinesNoAHGlobal) ) 1775 - 2 ^ ( (constPartNoAHGlobal-redPeNoAHGlobal) / (invRedExp*nActiveLinesNoAHGlobal) ) ) 1776 */ 1777 int scale0 = 0; 1778 int scale1 = 0; 1779 1780 FIXP_DBL tmp0 = CalcRedValPower( constPartNoAHGlobal-desiredPeNoAHGlobal, 4*nActiveLinesNoAHGlobal, &scale0 ); 1781 FIXP_DBL tmp1 = CalcRedValPower( constPartNoAHGlobal-redPeNoAHGlobal, 4*nActiveLinesNoAHGlobal, &scale1 ); 1782 1783 int scalMin = FDKmin(scale0, scale1)-1; 1784 1785 tmp0 = scaleValue(tmp0,(scalMin-scale0)) - scaleValue(tmp1,(scalMin-scale1)); 1786 scale0 = scalMin; 1787 1788 /* old reduction value */ 1789 tmp1 = redValue[elementId]; 1790 scale1 = redValScaling[elementId]; 1791 1792 scalMin = fixMin(scale0,scale1)-1; 1793 1794 /* sum up old and new reduction value */ 1795 redValue[elementId] = scaleValue(tmp0,(scalMin-scale0)) + scaleValue(tmp1,(scalMin-scale1)); 1796 redValScaling[elementId] = scalMin; 1797 1798 } /* EOF DSE-suppression */ 1799 } /* EOF for all elements... */ 1800 } /* nActiveLinesNoAHGlobal > 0 */ 1801 } 1802 else { 1803 /* desiredPe >= redPeGlobal */ 1804 for (elementId = elementOffset;elementId<nElements;elementId++) { 1805 if (cm->elInfo[elementId].elType != ID_DSE) { 1806 1807 INT redVal_scale = 0; 1808 FIXP_DBL tmp = fDivNorm((FIXP_DBL)redPeGlobal, (FIXP_DBL)desiredPe, &redVal_scale); 1809 1810 /* redVal *= redPeGlobal/desiredPe; */ 1811 redValue[elementId] = fMult(redValue[elementId], tmp); 1812 redValScaling[elementId] -= redVal_scale; 1813 1814 FDKaacEnc_resetAHFlags(pAhFlag[elementId], cm->elInfo[elementId].nChannelsInEl, psyOutElement[elementId]->psyOutChannel); 1815 } /* EOF DSE-suppression */ 1816 } /* EOF for all elements... */ 1817 } 1818 1819 redPeGlobal = 0; 1820 /* Calculate new redVal's PE... */ 1821 for (elementId = elementOffset;elementId<nElements;elementId++) { 1822 if (cm->elInfo[elementId].elType != ID_DSE) { 1823 1824 INT nChannels = cm->elInfo[elementId].nChannelsInEl; 1825 PE_DATA *peData = &qcElement[elementId]->peData; 1826 1827 /* reduce thresholds */ 1828 FDKaacEnc_reduceThresholdsCBR(qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], pThrExp[elementId], nChannels, redValue[elementId], redValScaling[elementId]); 1829 1830 /* pe after second guess */ 1831 FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, qcElement[elementId]->qcOutChannel, peData, nChannels); 1832 redPeGlobal += peData->pe; 1833 1834 } /* EOF DSE-suppression */ 1835 } /* EOF for all elements... */ 1836 1837 iter++; 1838 } /* EOF while */ 1839 1840 1841 /* ------------------------------------------------------- */ 1842 /* Part IV: if still required, further reduce constraints */ 1843 /* ------------------------------------------------------- */ 1844 /* 1.0* 1.15* 1.20* 1845 * desiredPe desiredPe desiredPe 1846 * | | | 1847 * ...XXXXXXXXXXXXXXXXXXXXXXXXXXX| | 1848 * | | |XXXXXXXXXXX... 1849 * | |XXXXXXXXXXX| 1850 * --- A --- | --- B --- | --- C --- 1851 * 1852 * (X): redPeGlobal 1853 * (A): FDKaacEnc_correctThresh() 1854 * (B): FDKaacEnc_allowMoreHoles() 1855 * (C): FDKaacEnc_reduceMinSnr() 1856 */ 1857 1858 /* correct thresholds to get closer to the desired pe */ 1859 if ( redPeGlobal > desiredPe ) { 1860 FDKaacEnc_correctThresh(cm, qcElement, psyOutElement, pAhFlag, pThrExp, redValue, redValScaling, 1861 desiredPe - redPeGlobal, processElements, elementOffset); 1862 1863 /* update PE */ 1864 redPeGlobal = 0; 1865 for(elementId=elementOffset;elementId<nElements;elementId++) { 1866 if (cm->elInfo[elementId].elType != ID_DSE) { 1867 1868 INT nChannels = cm->elInfo[elementId].nChannelsInEl; 1869 PE_DATA *peData = &qcElement[elementId]->peData; 1870 1871 /* pe after correctThresh */ 1872 FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, qcElement[elementId]->qcOutChannel, peData, nChannels); 1873 redPeGlobal += peData->pe; 1874 1875 } /* EOF DSE-suppression */ 1876 } /* EOF for all elements... */ 1877 } 1878 1879 if ( redPeGlobal > desiredPe ) { 1880 /* reduce pe by reducing minSnr requirements */ 1881 FDKaacEnc_reduceMinSnr(cm, qcElement, psyOutElement, pAhFlag, 1882 (fMultI(FL2FXCONST_DBL(0.15f),desiredPe) + desiredPe), 1883 &redPeGlobal, processElements, elementOffset); 1884 1885 /* reduce pe by allowing additional spectral holes */ 1886 FDKaacEnc_allowMoreHoles(cm, qcElement, psyOutElement, AdjThrStateElement, pAhFlag, 1887 desiredPe, redPeGlobal, processElements, elementOffset); 1888 } 1889 1890} 1891 1892/* similar to FDKaacEnc_adaptThresholdsToPe(), for VBR-mode */ 1893void FDKaacEnc_AdaptThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], 1894 PSY_OUT_CHANNEL* psyOutChannel[(2)], 1895 ATS_ELEMENT* AdjThrStateElement, 1896 struct TOOLSINFO *toolsInfo, 1897 PE_DATA *peData, 1898 const INT nChannels) 1899{ 1900 UCHAR (*pAhFlag)[MAX_GROUPED_SFB]; 1901 FIXP_DBL (*pThrExp)[MAX_GROUPED_SFB]; 1902 1903 /* allocate scratch memory */ 1904 C_ALLOC_SCRATCH_START(_pAhFlag, UCHAR, (2)*MAX_GROUPED_SFB) 1905 C_ALLOC_SCRATCH_START(_pThrExp, FIXP_DBL, (2)*MAX_GROUPED_SFB) 1906 pAhFlag = (UCHAR(*)[MAX_GROUPED_SFB])_pAhFlag; 1907 pThrExp = (FIXP_DBL(*)[MAX_GROUPED_SFB])_pThrExp; 1908 1909 /* thresholds to the power of redExp */ 1910 FDKaacEnc_calcThreshExp(pThrExp, qcOutChannel, psyOutChannel, nChannels); 1911 1912 /* lower the minSnr requirements for low energies compared to the average 1913 energy in this frame */ 1914 FDKaacEnc_adaptMinSnr(qcOutChannel, psyOutChannel, &AdjThrStateElement->minSnrAdaptParam, nChannels); 1915 1916 /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ 1917 FDKaacEnc_initAvoidHoleFlag(qcOutChannel, psyOutChannel, pAhFlag, toolsInfo, 1918 nChannels, peData, &AdjThrStateElement->ahParam); 1919 1920 /* reduce thresholds */ 1921 FDKaacEnc_reduceThresholdsVBR(qcOutChannel, psyOutChannel, pAhFlag, pThrExp, nChannels, 1922 AdjThrStateElement->vbrQualFactor, 1923 &AdjThrStateElement->chaosMeasureOld); 1924 1925 /* free scratch memory */ 1926 C_ALLOC_SCRATCH_END(_pThrExp, FIXP_DBL, (2)*MAX_GROUPED_SFB) 1927 C_ALLOC_SCRATCH_END(_pAhFlag, UCHAR, (2)*MAX_GROUPED_SFB) 1928} 1929 1930 1931/***************************************************************************** 1932 1933 functionname: FDKaacEnc_calcBitSave 1934 description: Calculates percentage of bit save, see figure below 1935 returns: 1936 input: parameters and bitres-fullness 1937 output: percentage of bit save 1938 1939*****************************************************************************/ 1940/* 1941 bitsave 1942 maxBitSave(%)| clipLow 1943 |---\ 1944 | \ 1945 | \ 1946 | \ 1947 | \ 1948 |--------\--------------> bitres 1949 | \ 1950 minBitSave(%)| \------------ 1951 clipHigh maxBitres 1952*/ 1953static FIXP_DBL FDKaacEnc_calcBitSave(FIXP_DBL fillLevel, 1954 const FIXP_DBL clipLow, 1955 const FIXP_DBL clipHigh, 1956 const FIXP_DBL minBitSave, 1957 const FIXP_DBL maxBitSave, 1958 const FIXP_DBL bitsave_slope) 1959{ 1960 FIXP_DBL bitsave; 1961 1962 fillLevel = fixMax(fillLevel, clipLow); 1963 fillLevel = fixMin(fillLevel, clipHigh); 1964 1965 bitsave = maxBitSave - fMult((fillLevel-clipLow), bitsave_slope); 1966 1967 return (bitsave); 1968} 1969 1970/***************************************************************************** 1971 1972 functionname: FDKaacEnc_calcBitSpend 1973 description: Calculates percentage of bit spend, see figure below 1974 returns: 1975 input: parameters and bitres-fullness 1976 output: percentage of bit spend 1977 1978*****************************************************************************/ 1979/* 1980 bitspend clipHigh 1981 maxBitSpend(%)| /-----------maxBitres 1982 | / 1983 | / 1984 | / 1985 | / 1986 | / 1987 |----/-----------------> bitres 1988 | / 1989 minBitSpend(%)|--/ 1990 clipLow 1991*/ 1992static FIXP_DBL FDKaacEnc_calcBitSpend(FIXP_DBL fillLevel, 1993 const FIXP_DBL clipLow, 1994 const FIXP_DBL clipHigh, 1995 const FIXP_DBL minBitSpend, 1996 const FIXP_DBL maxBitSpend, 1997 const FIXP_DBL bitspend_slope) 1998{ 1999 FIXP_DBL bitspend; 2000 2001 fillLevel = fixMax(fillLevel, clipLow); 2002 fillLevel = fixMin(fillLevel, clipHigh); 2003 2004 bitspend = minBitSpend + fMult(fillLevel-clipLow, bitspend_slope); 2005 2006 return (bitspend); 2007} 2008 2009 2010/***************************************************************************** 2011 2012 functionname: FDKaacEnc_adjustPeMinMax() 2013 description: adjusts peMin and peMax parameters over time 2014 returns: 2015 input: current pe, peMin, peMax, bitres size 2016 output: adjusted peMin/peMax 2017 2018*****************************************************************************/ 2019static void FDKaacEnc_adjustPeMinMax(const INT currPe, 2020 INT *peMin, 2021 INT *peMax) 2022{ 2023 FIXP_DBL minFacHi = FL2FXCONST_DBL(0.3f), maxFacHi = (FIXP_DBL)MAXVAL_DBL, minFacLo = FL2FXCONST_DBL(0.14f), maxFacLo = FL2FXCONST_DBL(0.07f); 2024 INT diff; 2025 2026 INT minDiff_fix = fMultI(FL2FXCONST_DBL(0.1666666667f), currPe); 2027 2028 if (currPe > *peMax) 2029 { 2030 diff = (currPe-*peMax) ; 2031 *peMin += fMultI(minFacHi,diff); 2032 *peMax += fMultI(maxFacHi,diff); 2033 } 2034 else if (currPe < *peMin) 2035 { 2036 diff = (*peMin-currPe) ; 2037 *peMin -= fMultI(minFacLo,diff); 2038 *peMax -= fMultI(maxFacLo,diff); 2039 } 2040 else 2041 { 2042 *peMin += fMultI(minFacHi, (currPe - *peMin)); 2043 *peMax -= fMultI(maxFacLo, (*peMax - currPe)); 2044 } 2045 2046 if ((*peMax - *peMin) < minDiff_fix) 2047 { 2048 INT peMax_fix = *peMax, peMin_fix = *peMin; 2049 FIXP_DBL partLo_fix, partHi_fix; 2050 2051 partLo_fix = (FIXP_DBL)fixMax(0, currPe - peMin_fix); 2052 partHi_fix = (FIXP_DBL)fixMax(0, peMax_fix - currPe); 2053 2054 peMax_fix = (INT)(currPe + fMultI(fDivNorm(partHi_fix, (partLo_fix+partHi_fix)), minDiff_fix)); 2055 peMin_fix = (INT)(currPe - fMultI(fDivNorm(partLo_fix, (partLo_fix+partHi_fix)), minDiff_fix)); 2056 peMin_fix = fixMax(0, peMin_fix); 2057 2058 *peMax = peMax_fix; 2059 *peMin = peMin_fix; 2060 } 2061} 2062 2063 2064 2065/***************************************************************************** 2066 2067 functionname: BitresCalcBitFac 2068 description: calculates factor of spending bits for one frame 2069 1.0 : take all frame dynpart bits 2070 >1.0 : take all frame dynpart bits + bitres 2071 <1.0 : put bits in bitreservoir 2072 returns: BitFac 2073 input: bitres-fullness, pe, blockType, parameter-settings 2074 output: 2075 2076*****************************************************************************/ 2077/* 2078 bitfac(%) pemax 2079 bitspend(%) | /-----------maxBitres 2080 | / 2081 | / 2082 | / 2083 | / 2084 | / 2085 |----/-----------------> pe 2086 | / 2087 bitsave(%) |--/ 2088 pemin 2089*/ 2090 2091static FIXP_DBL FDKaacEnc_bitresCalcBitFac(const INT bitresBits, 2092 const INT maxBitresBits, 2093 const INT pe, 2094 const INT lastWindowSequence, 2095 const INT avgBits, 2096 const FIXP_DBL maxBitFac, 2097 ADJ_THR_STATE *AdjThr, 2098 ATS_ELEMENT *adjThrChan) 2099{ 2100 BRES_PARAM *bresParam; 2101 INT pex; 2102 2103 INT qmin, qbr, qbres, qmbr; 2104 FIXP_DBL bitSave, bitSpend; 2105 2106 FIXP_DBL bitresFac_fix, tmp_cst, tmp_fix; 2107 FIXP_DBL pe_pers, bits_ratio, maxBrVal; 2108 FIXP_DBL bitsave_slope, bitspend_slope, maxBitFac_tmp; 2109 FIXP_DBL fillLevel_fix = (FIXP_DBL)0x7fffffff; 2110 FIXP_DBL UNITY = (FIXP_DBL)0x7fffffff; 2111 FIXP_DBL POINT7 = (FIXP_DBL)0x5999999A; 2112 2113 if (maxBitresBits > bitresBits) { 2114 fillLevel_fix = fDivNorm(bitresBits, maxBitresBits); 2115 } 2116 2117 if (lastWindowSequence != SHORT_WINDOW) 2118 { 2119 bresParam = &(AdjThr->bresParamLong); 2120 bitsave_slope = (FIXP_DBL)0x3BBBBBBC; 2121 bitspend_slope = (FIXP_DBL)0x55555555; 2122 } 2123 else 2124 { 2125 bresParam = &(AdjThr->bresParamShort); 2126 bitsave_slope = (FIXP_DBL)0x2E8BA2E9; 2127 bitspend_slope = (FIXP_DBL)0x7fffffff; 2128 } 2129 2130 pex = fixMax(pe, adjThrChan->peMin); 2131 pex = fixMin(pex, adjThrChan->peMax); 2132 2133 bitSave = FDKaacEnc_calcBitSave(fillLevel_fix, 2134 bresParam->clipSaveLow, bresParam->clipSaveHigh, 2135 bresParam->minBitSave, bresParam->maxBitSave, bitsave_slope); 2136 2137 bitSpend = FDKaacEnc_calcBitSpend(fillLevel_fix, 2138 bresParam->clipSpendLow, bresParam->clipSpendHigh, 2139 bresParam->minBitSpend, bresParam->maxBitSpend, bitspend_slope); 2140 2141 pe_pers = fDivNorm(pex - adjThrChan->peMin, adjThrChan->peMax - adjThrChan->peMin); 2142 tmp_fix = fMult(((FIXP_DBL)bitSpend + (FIXP_DBL)bitSave), pe_pers); 2143 bitresFac_fix = (UNITY>>1) - ((FIXP_DBL)bitSave>>1) + (tmp_fix>>1); qbres = (DFRACT_BITS-2); 2144 2145 /* (float)bitresBits/(float)avgBits */ 2146 bits_ratio = fDivNorm(bitresBits, avgBits, &qbr); 2147 qbr = DFRACT_BITS-1-qbr; 2148 2149 /* Add 0.7 in q31 to bits_ratio in qbr */ 2150 /* 0.7f + (float)bitresBits/(float)avgBits */ 2151 qmin = fixMin(qbr, (DFRACT_BITS-1)); 2152 bits_ratio = bits_ratio >> (qbr - qmin); 2153 tmp_cst = POINT7 >> ((DFRACT_BITS-1) - qmin); 2154 maxBrVal = (bits_ratio>>1) + (tmp_cst>>1); qmbr = qmin - 1; 2155 2156 /* bitresFac_fix = fixMin(bitresFac_fix, 0.7 + bitresBits/avgBits); */ 2157 bitresFac_fix = bitresFac_fix >> (qbres - qmbr); qbres = qmbr; 2158 bitresFac_fix = fixMin(bitresFac_fix, maxBrVal); 2159 2160 /* Compare with maxBitFac */ 2161 qmin = fixMin(Q_BITFAC, qbres); 2162 bitresFac_fix = bitresFac_fix >> (qbres - qmin); 2163 maxBitFac_tmp = maxBitFac >> (Q_BITFAC - qmin); 2164 if(maxBitFac_tmp < bitresFac_fix) 2165 { 2166 bitresFac_fix = maxBitFac; 2167 } 2168 else 2169 { 2170 if(qmin < Q_BITFAC) 2171 { 2172 bitresFac_fix = bitresFac_fix << (Q_BITFAC-qmin); 2173 } 2174 else 2175 { 2176 bitresFac_fix = bitresFac_fix >> (qmin-Q_BITFAC); 2177 } 2178 } 2179 2180 FDKaacEnc_adjustPeMinMax(pe, &adjThrChan->peMin, &adjThrChan->peMax); 2181 2182 return bitresFac_fix; 2183} 2184 2185 2186/***************************************************************************** 2187functionname: FDKaacEnc_AdjThrNew 2188description: allocate ADJ_THR_STATE 2189*****************************************************************************/ 2190INT FDKaacEnc_AdjThrNew(ADJ_THR_STATE** phAdjThr, 2191 INT nElements) 2192{ 2193 INT err = 0; 2194 INT i; 2195 ADJ_THR_STATE* hAdjThr = GetRam_aacEnc_AdjustThreshold(); 2196 if (hAdjThr==NULL) { 2197 err = 1; 2198 goto bail; 2199 } 2200 2201 for (i=0; i<nElements; i++) { 2202 hAdjThr->adjThrStateElem[i] = GetRam_aacEnc_AdjThrStateElement(i); 2203 if (hAdjThr->adjThrStateElem[i]==NULL) { 2204 err = 1; 2205 goto bail; 2206 } 2207 } 2208 2209bail: 2210 *phAdjThr = hAdjThr; 2211 return err; 2212} 2213 2214 2215/***************************************************************************** 2216functionname: FDKaacEnc_AdjThrInit 2217description: initialize ADJ_THR_STATE 2218*****************************************************************************/ 2219void FDKaacEnc_AdjThrInit( 2220 ADJ_THR_STATE *hAdjThr, 2221 const INT meanPe, 2222 ELEMENT_BITS *elBits[(8)], 2223 INT invQuant, 2224 INT nElements, 2225 INT nChannelsEff, 2226 INT sampleRate, 2227 INT advancedBitsToPe, 2228 FIXP_DBL vbrQualFactor 2229 ) 2230{ 2231 INT i; 2232 2233 FIXP_DBL POINT8 = FL2FXCONST_DBL(0.8f); 2234 FIXP_DBL POINT6 = FL2FXCONST_DBL(0.6f); 2235 2236 /* common for all elements: */ 2237 /* parameters for bitres control */ 2238 hAdjThr->bresParamLong.clipSaveLow = (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */ 2239 hAdjThr->bresParamLong.clipSaveHigh = (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */ 2240 hAdjThr->bresParamLong.minBitSave = (FIXP_DBL)0xf999999a; /* FL2FXCONST_DBL(-0.05f); */ 2241 hAdjThr->bresParamLong.maxBitSave = (FIXP_DBL)0x26666666; /* FL2FXCONST_DBL(0.3f); */ 2242 hAdjThr->bresParamLong.clipSpendLow = (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */ 2243 hAdjThr->bresParamLong.clipSpendHigh = (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */ 2244 hAdjThr->bresParamLong.minBitSpend = (FIXP_DBL)0xf3333333; /* FL2FXCONST_DBL(-0.10f); */ 2245 hAdjThr->bresParamLong.maxBitSpend = (FIXP_DBL)0x33333333; /* FL2FXCONST_DBL(0.4f); */ 2246 2247 hAdjThr->bresParamShort.clipSaveLow = (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ 2248 hAdjThr->bresParamShort.clipSaveHigh = (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */ 2249 hAdjThr->bresParamShort.minBitSave = (FIXP_DBL)0x00000000; /* FL2FXCONST_DBL(0.0f); */ 2250 hAdjThr->bresParamShort.maxBitSave = (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ 2251 hAdjThr->bresParamShort.clipSpendLow = (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ 2252 hAdjThr->bresParamShort.clipSpendHigh = (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */ 2253 hAdjThr->bresParamShort.minBitSpend = (FIXP_DBL)0xf9999998; /* FL2FXCONST_DBL(-0.05f); */ 2254 hAdjThr->bresParamShort.maxBitSpend = (FIXP_DBL)0x40000000; /* FL2FXCONST_DBL(0.5f); */ 2255 2256 /* specific for each element: */ 2257 for (i=0; i<nElements; i++) { 2258 ATS_ELEMENT* atsElem = hAdjThr->adjThrStateElem[i]; 2259 MINSNR_ADAPT_PARAM *msaParam = &atsElem->minSnrAdaptParam; 2260 INT chBitrate = elBits[i]->chBitrateEl; 2261 2262 /* parameters for bitres control */ 2263 atsElem->peMin = fMultI(POINT8, meanPe) >> 1; 2264 atsElem->peMax = fMultI(POINT6, meanPe); 2265 2266 /* for use in FDKaacEnc_reduceThresholdsVBR */ 2267 atsElem->chaosMeasureOld = FL2FXCONST_DBL(0.3f); 2268 2269 /* additional pe offset to correct pe2bits for low bitrates */ 2270 atsElem->peOffset = 0; 2271 2272 /* vbr initialisation */ 2273 atsElem->vbrQualFactor = vbrQualFactor; 2274 if (chBitrate < 32000) 2275 { 2276 atsElem->peOffset = fixMax(50, 100-fMultI((FIXP_DBL)0x666667, chBitrate)); 2277 } 2278 2279 /* avoid hole parameters */ 2280 if (chBitrate > 20000) { 2281 atsElem->ahParam.modifyMinSnr = TRUE; 2282 atsElem->ahParam.startSfbL = 15; 2283 atsElem->ahParam.startSfbS = 3; 2284 } 2285 else { 2286 atsElem->ahParam.modifyMinSnr = FALSE; 2287 atsElem->ahParam.startSfbL = 0; 2288 atsElem->ahParam.startSfbS = 0; 2289 } 2290 2291 /* minSnr adaptation */ 2292 msaParam->maxRed = FL2FXCONST_DBL(0.00390625f); /* 0.25f/64.0f */ 2293 /* start adaptation of minSnr for avgEn/sfbEn > startRatio */ 2294 msaParam->startRatio = FL2FXCONST_DBL(0.05190512648f); /* ld64(10.0f) */ 2295 /* maximum minSnr reduction to minSnr^maxRed is reached for 2296 avgEn/sfbEn >= maxRatio */ 2297 /* msaParam->maxRatio = 1000.0f; */ 2298 /*msaParam->redRatioFac = ((float)1.0f - msaParam->maxRed) / ((float)10.0f*log10(msaParam->startRatio/msaParam->maxRatio)/log10(2.0f)*(float)0.3010299956f);*/ 2299 msaParam->redRatioFac = FL2FXCONST_DBL(-0.375f); /* -0.0375f * 10.0f */ 2300 /*msaParam->redOffs = (float)1.0f - msaParam->redRatioFac * (float)10.0f * log10(msaParam->startRatio)/log10(2.0f) * (float)0.3010299956f;*/ 2301 msaParam->redOffs = FL2FXCONST_DBL(0.021484375); /* 1.375f/64.0f */ 2302 2303 /* init pe correction */ 2304 atsElem->peCorrectionFactor_m = FL2FXCONST_DBL(0.5f); /* 1.0 */ 2305 atsElem->peCorrectionFactor_e = 1; 2306 2307 atsElem->dynBitsLast = -1; 2308 atsElem->peLast = 0; 2309 2310 /* init bits to pe factor */ 2311 2312 /* init bits2PeFactor */ 2313 FDKaacEnc_InitBits2PeFactor( 2314 &atsElem->bits2PeFactor_m, 2315 &atsElem->bits2PeFactor_e, 2316 chBitrate, /* bitrate/channel*/ 2317 nChannelsEff, /* number of channels */ 2318 sampleRate, 2319 advancedBitsToPe, 2320 invQuant 2321 ); 2322 2323 } /* for nElements */ 2324 2325} 2326 2327 2328/***************************************************************************** 2329 functionname: FDKaacEnc_FDKaacEnc_calcPeCorrection 2330 description: calc desired pe 2331*****************************************************************************/ 2332static void FDKaacEnc_FDKaacEnc_calcPeCorrection( 2333 FIXP_DBL *const correctionFac_m, 2334 INT *const correctionFac_e, 2335 const INT peAct, 2336 const INT peLast, 2337 const INT bitsLast, 2338 const FIXP_DBL bits2PeFactor_m, 2339 const INT bits2PeFactor_e 2340 ) 2341{ 2342 if ( (bitsLast > 0) && (peAct < 1.5f*peLast) && (peAct > 0.7f*peLast) && 2343 (FDKaacEnc_bits2pe2(bitsLast, fMult(FL2FXCONST_DBL(1.2f/2.f), bits2PeFactor_m), bits2PeFactor_e+1) > peLast) && 2344 (FDKaacEnc_bits2pe2(bitsLast, fMult(FL2FXCONST_DBL(0.65f), bits2PeFactor_m), bits2PeFactor_e ) < peLast) ) 2345 { 2346 FIXP_DBL corrFac = *correctionFac_m; 2347 2348 int scaling = 0; 2349 FIXP_DBL denum = (FIXP_DBL)FDKaacEnc_bits2pe2(bitsLast, bits2PeFactor_m, bits2PeFactor_e); 2350 FIXP_DBL newFac = fDivNorm((FIXP_DBL)peLast, denum, &scaling); 2351 2352 /* dead zone, newFac and corrFac are scaled by 0.5 */ 2353 if ((FIXP_DBL)peLast <= denum) { /* ratio <= 1.f */ 2354 newFac = fixMax(scaleValue(fixMin( fMult(FL2FXCONST_DBL(1.1f/2.f), newFac), scaleValue(FL2FXCONST_DBL( 1.f/2.f), -scaling)), scaling), FL2FXCONST_DBL(0.85f/2.f) ); 2355 } 2356 else { /* ratio < 1.f */ 2357 newFac = fixMax( fixMin( scaleValue(fMult(FL2FXCONST_DBL(0.9f/2.f), newFac), scaling), FL2FXCONST_DBL(1.15f/2.f) ), FL2FXCONST_DBL( 1.f/2.f) ); 2358 } 2359 2360 if ( ((newFac > FL2FXCONST_DBL(1.f/2.f)) && (corrFac < FL2FXCONST_DBL(1.f/2.f))) 2361 || ((newFac < FL2FXCONST_DBL(1.f/2.f)) && (corrFac > FL2FXCONST_DBL(1.f/2.f)))) 2362 { 2363 corrFac = FL2FXCONST_DBL(1.f/2.f); 2364 } 2365 2366 /* faster adaptation towards 1.0, slower in the other direction */ 2367 if ( (corrFac < FL2FXCONST_DBL(1.f/2.f) && newFac < corrFac) 2368 || (corrFac > FL2FXCONST_DBL(1.f/2.f) && newFac > corrFac) ) 2369 { 2370 corrFac = fMult(FL2FXCONST_DBL(0.85f), corrFac) + fMult(FL2FXCONST_DBL(0.15f), newFac); 2371 } 2372 else { 2373 corrFac = fMult(FL2FXCONST_DBL(0.7f), corrFac) + fMult(FL2FXCONST_DBL(0.3f), newFac); 2374 } 2375 2376 corrFac = fixMax( fixMin( corrFac, FL2FXCONST_DBL(1.15f/2.f) ), FL2FXCONST_DBL(0.85/2.f) ); 2377 2378 *correctionFac_m = corrFac; 2379 *correctionFac_e = 1; 2380 } 2381 else { 2382 *correctionFac_m = FL2FXCONST_DBL(1.f/2.f); 2383 *correctionFac_e = 1; 2384 } 2385} 2386 2387 2388static void FDKaacEnc_calcPeCorrectionLowBitRes( 2389 FIXP_DBL *const correctionFac_m, 2390 INT *const correctionFac_e, 2391 const INT peLast, 2392 const INT bitsLast, 2393 const INT bitresLevel, 2394 const INT nChannels, 2395 const FIXP_DBL bits2PeFactor_m, 2396 const INT bits2PeFactor_e 2397 ) 2398{ 2399 /* tuning params */ 2400 const FIXP_DBL amp = FL2FXCONST_DBL(0.005); 2401 const FIXP_DBL maxDiff = FL2FXCONST_DBL(0.25f); 2402 2403 if (bitsLast > 0) { 2404 2405 /* Estimate deviation of granted and used dynamic bits in previous frame, in PE units */ 2406 const int bitsBalLast = peLast - FDKaacEnc_bits2pe2( 2407 bitsLast, 2408 bits2PeFactor_m, 2409 bits2PeFactor_e); 2410 2411 /* reserve n bits per channel */ 2412 int headroom = (bitresLevel>=50*nChannels) ? 0 : (100*nChannels); 2413 2414 /* in PE units */ 2415 headroom = FDKaacEnc_bits2pe2( 2416 headroom, 2417 bits2PeFactor_m, 2418 bits2PeFactor_e); 2419 2420 /* 2421 * diff = amp * ((bitsBalLast - headroom) / (bitresLevel + headroom) 2422 * diff = max ( min ( diff, maxDiff, -maxDiff)) / 2 2423 */ 2424 FIXP_DBL denominator = (FIXP_DBL)FDKaacEnc_bits2pe2(bitresLevel, bits2PeFactor_m, bits2PeFactor_e) + (FIXP_DBL)headroom; 2425 2426 int scaling = 0; 2427 FIXP_DBL diff = (bitsBalLast>=headroom) 2428 ? fMult(amp, fDivNorm( (FIXP_DBL)(bitsBalLast - headroom), denominator, &scaling)) 2429 : -fMult(amp, fDivNorm(-(FIXP_DBL)(bitsBalLast - headroom), denominator, &scaling)) ; 2430 2431 scaling -= 1; /* divide by 2 */ 2432 2433 diff = (scaling<=0) ? FDKmax( FDKmin (diff>>(-scaling), maxDiff>>1), -maxDiff>>1) 2434 : FDKmax( FDKmin (diff, maxDiff>>(1+scaling)), -maxDiff>>(1+scaling)) << scaling; 2435 2436 /* 2437 * corrFac += diff 2438 * corrFac = max ( min ( corrFac/2.f, 1.f/2.f, 0.75f/2.f ) ) 2439 */ 2440 *correctionFac_m = FDKmax(FDKmin((*correctionFac_m)+diff, FL2FXCONST_DBL(1.0f/2.f)), FL2FXCONST_DBL(0.75f/2.f)) ; 2441 *correctionFac_e = 1; 2442 } 2443 else { 2444 *correctionFac_m = FL2FXCONST_DBL(0.75/2.f); 2445 *correctionFac_e = 1; 2446 } 2447} 2448 2449void FDKaacEnc_DistributeBits(ADJ_THR_STATE *adjThrState, 2450 ATS_ELEMENT *AdjThrStateElement, 2451 PSY_OUT_CHANNEL *psyOutChannel[(2)], 2452 PE_DATA *peData, 2453 INT *grantedPe, 2454 INT *grantedPeCorr, 2455 const INT nChannels, 2456 const INT commonWindow, 2457 const INT grantedDynBits, 2458 const INT bitresBits, 2459 const INT maxBitresBits, 2460 const FIXP_DBL maxBitFac, 2461 const INT bitDistributionMode) 2462{ 2463 FIXP_DBL bitFactor; 2464 INT noRedPe = peData->pe; 2465 2466 /* prefer short windows for calculation of bitFactor */ 2467 INT curWindowSequence = LONG_WINDOW; 2468 if (nChannels==2) { 2469 if ((psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) || 2470 (psyOutChannel[1]->lastWindowSequence == SHORT_WINDOW)) { 2471 curWindowSequence = SHORT_WINDOW; 2472 } 2473 } 2474 else { 2475 curWindowSequence = psyOutChannel[0]->lastWindowSequence; 2476 } 2477 2478 if (grantedDynBits >= 1) { 2479 if (bitDistributionMode!=0) { 2480 *grantedPe = FDKaacEnc_bits2pe2(grantedDynBits, AdjThrStateElement->bits2PeFactor_m, AdjThrStateElement->bits2PeFactor_e); 2481 } 2482 else 2483 { 2484 /* factor dependend on current fill level and pe */ 2485 bitFactor = FDKaacEnc_bitresCalcBitFac(bitresBits, maxBitresBits, noRedPe, 2486 curWindowSequence, grantedDynBits, maxBitFac, 2487 adjThrState, 2488 AdjThrStateElement 2489 ); 2490 2491 /* desired pe for actual frame */ 2492 /* Worst case max of grantedDynBits is = 1024 * 5.27 * 2 */ 2493 *grantedPe = FDKaacEnc_bits2pe2(grantedDynBits, 2494 fMult(bitFactor, AdjThrStateElement->bits2PeFactor_m), AdjThrStateElement->bits2PeFactor_e+(DFRACT_BITS-1-Q_BITFAC) 2495 ); 2496 } 2497 } 2498 else { 2499 *grantedPe = 0; /* prevent divsion by 0 */ 2500 } 2501 2502 /* correction of pe value */ 2503 switch (bitDistributionMode) { 2504 case 2: 2505 case 1: 2506 FDKaacEnc_calcPeCorrectionLowBitRes( 2507 &AdjThrStateElement->peCorrectionFactor_m, 2508 &AdjThrStateElement->peCorrectionFactor_e, 2509 AdjThrStateElement->peLast, 2510 AdjThrStateElement->dynBitsLast, 2511 bitresBits, 2512 nChannels, 2513 AdjThrStateElement->bits2PeFactor_m, 2514 AdjThrStateElement->bits2PeFactor_e 2515 ); 2516 break; 2517 case 0: 2518 default: 2519 FDKaacEnc_FDKaacEnc_calcPeCorrection( 2520 &AdjThrStateElement->peCorrectionFactor_m, 2521 &AdjThrStateElement->peCorrectionFactor_e, 2522 fixMin(*grantedPe, noRedPe), 2523 AdjThrStateElement->peLast, 2524 AdjThrStateElement->dynBitsLast, 2525 AdjThrStateElement->bits2PeFactor_m, 2526 AdjThrStateElement->bits2PeFactor_e 2527 ); 2528 break; 2529 } 2530 2531 *grantedPeCorr = (INT)(fMult((FIXP_DBL)(*grantedPe<<Q_AVGBITS), AdjThrStateElement->peCorrectionFactor_m) >> (Q_AVGBITS-AdjThrStateElement->peCorrectionFactor_e)); 2532 2533 /* update last pe */ 2534 AdjThrStateElement->peLast = *grantedPe; 2535 AdjThrStateElement->dynBitsLast = -1; 2536 2537} 2538 2539/***************************************************************************** 2540functionname: FDKaacEnc_AdjustThresholds 2541description: adjust thresholds 2542*****************************************************************************/ 2543void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)], 2544 QC_OUT_ELEMENT* qcElement[(8)], 2545 QC_OUT* qcOut, 2546 PSY_OUT_ELEMENT* psyOutElement[(8)], 2547 INT CBRbitrateMode, 2548 CHANNEL_MAPPING* cm) 2549{ 2550 int i; 2551 if (CBRbitrateMode) 2552 { 2553 /* In case, no bits must be shifted between different elements, */ 2554 /* an element-wise execution of the pe-dependent threshold- */ 2555 /* adaption becomes necessary... */ 2556 for (i=0; i<cm->nElements; i++) 2557 { 2558 ELEMENT_INFO elInfo = cm->elInfo[i]; 2559 2560 if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || 2561 (elInfo.elType == ID_LFE)) 2562 { 2563 /* qcElement[i]->grantedPe = 2000; */ /* Use this only for debugging */ 2564 //if (totalGrantedPeCorr < totalNoRedPe) { 2565 if (qcElement[i]->grantedPe < qcElement[i]->peData.pe) 2566 { 2567 /* calc threshold necessary for desired pe */ 2568 FDKaacEnc_adaptThresholdsToPe(cm, 2569 AdjThrStateElement, 2570 qcElement, 2571 psyOutElement, 2572 qcElement[i]->grantedPeCorr, 2573 1, /* Process only 1 element */ 2574 i); /* Process exactly THIS element */ 2575 2576 } 2577 2578 } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ 2579 2580 } /* -end- element loop */ 2581 } 2582 else { 2583 for (i=0; i<cm->nElements; i++) 2584 { 2585 ELEMENT_INFO elInfo = cm->elInfo[i]; 2586 2587 if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || 2588 (elInfo.elType == ID_LFE)) 2589 { 2590 /* for VBR-mode */ 2591 FDKaacEnc_AdaptThresholdsVBR(qcElement[i]->qcOutChannel, 2592 psyOutElement[i]->psyOutChannel, 2593 AdjThrStateElement[i], 2594 &psyOutElement[i]->toolsInfo, 2595 &qcElement[i]->peData, 2596 cm->elInfo[i].nChannelsInEl); 2597 } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ 2598 2599 } /* -end- element loop */ 2600 2601 } 2602 for (i=0; i<cm->nElements; i++) { 2603 int ch,sfb,sfbGrp; 2604 /* no weighting of threholds and energies for mlout */ 2605 /* weight energies and thresholds */ 2606 for (ch=0; ch<cm->elInfo[i].nChannelsInEl; ch++) { 2607 QC_OUT_CHANNEL* pQcOutCh = qcElement[i]->qcOutChannel[ch]; 2608 for (sfbGrp = 0;sfbGrp < psyOutElement[i]->psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutElement[i]->psyOutChannel[ch]->sfbPerGroup) { 2609 for (sfb=0; sfb<psyOutElement[i]->psyOutChannel[ch]->maxSfbPerGroup; sfb++) { 2610 pQcOutCh->sfbThresholdLdData[sfb+sfbGrp] += pQcOutCh->sfbEnFacLd[sfb+sfbGrp]; 2611 } 2612 } 2613 } 2614 } 2615} 2616 2617void FDKaacEnc_AdjThrClose(ADJ_THR_STATE** phAdjThr) 2618{ 2619 INT i; 2620 ADJ_THR_STATE* hAdjThr = *phAdjThr; 2621 2622 if (hAdjThr!=NULL) { 2623 for (i=0; i<(8); i++) { 2624 if (hAdjThr->adjThrStateElem[i]!=NULL) { 2625 FreeRam_aacEnc_AdjThrStateElement(&hAdjThr->adjThrStateElem[i]); 2626 } 2627 } 2628 FreeRam_aacEnc_AdjustThreshold(phAdjThr); 2629 } 2630} 2631 2632