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