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 - 2021 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 /*********************** MPEG surround decoder library *************************
96*e5436536SAndroid Build Coastguard Worker
97*e5436536SAndroid Build Coastguard Worker Author(s):
98*e5436536SAndroid Build Coastguard Worker
99*e5436536SAndroid Build Coastguard Worker Description: SAC Dec guided envelope shaping
100*e5436536SAndroid Build Coastguard Worker
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker
103*e5436536SAndroid Build Coastguard Worker #include "sac_reshapeBBEnv.h"
104*e5436536SAndroid Build Coastguard Worker
105*e5436536SAndroid Build Coastguard Worker #include "sac_dec.h"
106*e5436536SAndroid Build Coastguard Worker #include "sac_bitdec.h"
107*e5436536SAndroid Build Coastguard Worker #include "sac_calcM1andM2.h"
108*e5436536SAndroid Build Coastguard Worker #include "sac_reshapeBBEnv.h"
109*e5436536SAndroid Build Coastguard Worker #include "sac_rom.h"
110*e5436536SAndroid Build Coastguard Worker
111*e5436536SAndroid Build Coastguard Worker #define INP_DRY_WET 0
112*e5436536SAndroid Build Coastguard Worker #define INP_DMX 1
113*e5436536SAndroid Build Coastguard Worker
114*e5436536SAndroid Build Coastguard Worker #define SF_SHAPE 1
115*e5436536SAndroid Build Coastguard Worker #define SF_DIV32 6
116*e5436536SAndroid Build Coastguard Worker #define SF_FACTOR_SLOT 5
117*e5436536SAndroid Build Coastguard Worker
118*e5436536SAndroid Build Coastguard Worker #define START_BB_ENV 0 /* 10 */
119*e5436536SAndroid Build Coastguard Worker #define END_BB_ENV 9 /* 18 */
120*e5436536SAndroid Build Coastguard Worker
121*e5436536SAndroid Build Coastguard Worker #define SF_ALPHA1 8
122*e5436536SAndroid Build Coastguard Worker #define SF_BETA1 4
123*e5436536SAndroid Build Coastguard Worker
initBBEnv(spatialDec * self,int initStatesFlag)124*e5436536SAndroid Build Coastguard Worker void initBBEnv(spatialDec *self, int initStatesFlag) {
125*e5436536SAndroid Build Coastguard Worker INT ch, k;
126*e5436536SAndroid Build Coastguard Worker
127*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < self->numOutputChannels; ch++) {
128*e5436536SAndroid Build Coastguard Worker k = row2channelGES[self->treeConfig][ch];
129*e5436536SAndroid Build Coastguard Worker self->row2channelDmxGES[ch] = k;
130*e5436536SAndroid Build Coastguard Worker if (k == -1) continue;
131*e5436536SAndroid Build Coastguard Worker
132*e5436536SAndroid Build Coastguard Worker switch (self->treeConfig) {
133*e5436536SAndroid Build Coastguard Worker case TREE_212:
134*e5436536SAndroid Build Coastguard Worker self->row2channelDmxGES[ch] = 0;
135*e5436536SAndroid Build Coastguard Worker break;
136*e5436536SAndroid Build Coastguard Worker default:;
137*e5436536SAndroid Build Coastguard Worker }
138*e5436536SAndroid Build Coastguard Worker }
139*e5436536SAndroid Build Coastguard Worker
140*e5436536SAndroid Build Coastguard Worker if (initStatesFlag) {
141*e5436536SAndroid Build Coastguard Worker for (k = 0; k < 2 * MAX_OUTPUT_CHANNELS + MAX_INPUT_CHANNELS; k++) {
142*e5436536SAndroid Build Coastguard Worker self->reshapeBBEnvState->normNrgPrev__FDK[k] =
143*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.5f); /* 32768.f*32768.f */
144*e5436536SAndroid Build Coastguard Worker self->reshapeBBEnvState->normNrgPrevSF[k] = DFRACT_BITS - 1;
145*e5436536SAndroid Build Coastguard Worker self->reshapeBBEnvState->partNrgPrevSF[k] = 0;
146*e5436536SAndroid Build Coastguard Worker self->reshapeBBEnvState->partNrgPrev2SF[k] = 0;
147*e5436536SAndroid Build Coastguard Worker self->reshapeBBEnvState->frameNrgPrevSF[k] = 0;
148*e5436536SAndroid Build Coastguard Worker }
149*e5436536SAndroid Build Coastguard Worker }
150*e5436536SAndroid Build Coastguard Worker
151*e5436536SAndroid Build Coastguard Worker self->reshapeBBEnvState->alpha__FDK =
152*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.99637845575f); /* FDKexp(-64 / (0.4f * 44100)) */
153*e5436536SAndroid Build Coastguard Worker self->reshapeBBEnvState->beta__FDK =
154*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.96436909488f); /* FDKexp(-64 / (0.04f * 44100)) */
155*e5436536SAndroid Build Coastguard Worker }
156*e5436536SAndroid Build Coastguard Worker
getSlotNrgHQ(FIXP_DBL * RESTRICT pReal,FIXP_DBL * RESTRICT pImag,FIXP_DBL * RESTRICT slotNrg,INT maxValSF,INT hybBands)157*e5436536SAndroid Build Coastguard Worker static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal,
158*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pImag,
159*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT slotNrg, INT maxValSF,
160*e5436536SAndroid Build Coastguard Worker INT hybBands) {
161*e5436536SAndroid Build Coastguard Worker INT qs;
162*e5436536SAndroid Build Coastguard Worker FIXP_DBL nrg;
163*e5436536SAndroid Build Coastguard Worker
164*e5436536SAndroid Build Coastguard Worker /* qs = 12, 13, 14 */
165*e5436536SAndroid Build Coastguard Worker slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
166*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
167*e5436536SAndroid Build Coastguard Worker slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
168*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
169*e5436536SAndroid Build Coastguard Worker slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
170*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
171*e5436536SAndroid Build Coastguard Worker /* qs = 15 */
172*e5436536SAndroid Build Coastguard Worker slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
173*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
174*e5436536SAndroid Build Coastguard Worker /* qs = 16, 17 */
175*e5436536SAndroid Build Coastguard Worker nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
176*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
177*e5436536SAndroid Build Coastguard Worker slotNrg[4] =
178*e5436536SAndroid Build Coastguard Worker nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
179*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
180*e5436536SAndroid Build Coastguard Worker /* qs = 18, 19, 20 */
181*e5436536SAndroid Build Coastguard Worker nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
182*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
183*e5436536SAndroid Build Coastguard Worker nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
184*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
185*e5436536SAndroid Build Coastguard Worker slotNrg[5] =
186*e5436536SAndroid Build Coastguard Worker nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
187*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
188*e5436536SAndroid Build Coastguard Worker /* qs = 21, 22 */
189*e5436536SAndroid Build Coastguard Worker nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
190*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
191*e5436536SAndroid Build Coastguard Worker slotNrg[6] =
192*e5436536SAndroid Build Coastguard Worker nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
193*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
194*e5436536SAndroid Build Coastguard Worker /* qs = 23, 24 */
195*e5436536SAndroid Build Coastguard Worker if (hybBands > 23) {
196*e5436536SAndroid Build Coastguard Worker slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
197*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
198*e5436536SAndroid Build Coastguard Worker slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
199*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
200*e5436536SAndroid Build Coastguard Worker /* qs = 25, 26, 29, 28, 29 */
201*e5436536SAndroid Build Coastguard Worker nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
202*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
203*e5436536SAndroid Build Coastguard Worker nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
204*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
205*e5436536SAndroid Build Coastguard Worker nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
206*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
207*e5436536SAndroid Build Coastguard Worker nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
208*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
209*e5436536SAndroid Build Coastguard Worker slotNrg[7] =
210*e5436536SAndroid Build Coastguard Worker nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
211*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
212*e5436536SAndroid Build Coastguard Worker /* qs = 30 ... min(41,hybBands-1) */
213*e5436536SAndroid Build Coastguard Worker nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
214*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
215*e5436536SAndroid Build Coastguard Worker for (qs = 31; qs < hybBands; qs++) {
216*e5436536SAndroid Build Coastguard Worker nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) +
217*e5436536SAndroid Build Coastguard Worker (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1)));
218*e5436536SAndroid Build Coastguard Worker }
219*e5436536SAndroid Build Coastguard Worker slotNrg[8] = nrg;
220*e5436536SAndroid Build Coastguard Worker } else {
221*e5436536SAndroid Build Coastguard Worker slotNrg[7] = (FIXP_DBL)0;
222*e5436536SAndroid Build Coastguard Worker slotNrg[8] = (FIXP_DBL)0;
223*e5436536SAndroid Build Coastguard Worker }
224*e5436536SAndroid Build Coastguard Worker }
225*e5436536SAndroid Build Coastguard Worker
combineDryWet(FIXP_DBL * RESTRICT pReal,FIXP_DBL * RESTRICT pImag,FIXP_DBL * RESTRICT pHybOutputRealDry,FIXP_DBL * RESTRICT pHybOutputImagDry,FIXP_DBL * RESTRICT pHybOutputRealWet,FIXP_DBL * RESTRICT pHybOutputImagWet,INT cplxBands,INT hybBands)226*e5436536SAndroid Build Coastguard Worker static inline void combineDryWet(FIXP_DBL *RESTRICT pReal,
227*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pImag,
228*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pHybOutputRealDry,
229*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pHybOutputImagDry,
230*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pHybOutputRealWet,
231*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pHybOutputImagWet,
232*e5436536SAndroid Build Coastguard Worker INT cplxBands, INT hybBands) {
233*e5436536SAndroid Build Coastguard Worker INT qs;
234*e5436536SAndroid Build Coastguard Worker
235*e5436536SAndroid Build Coastguard Worker for (qs = 12; qs < cplxBands; qs++) {
236*e5436536SAndroid Build Coastguard Worker pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
237*e5436536SAndroid Build Coastguard Worker pImag[qs] = (pHybOutputImagDry[qs] >> 1) + (pHybOutputImagWet[qs] >> 1);
238*e5436536SAndroid Build Coastguard Worker }
239*e5436536SAndroid Build Coastguard Worker for (; qs < hybBands; qs++) {
240*e5436536SAndroid Build Coastguard Worker pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1);
241*e5436536SAndroid Build Coastguard Worker }
242*e5436536SAndroid Build Coastguard Worker }
243*e5436536SAndroid Build Coastguard Worker
slotAmp(FIXP_DBL * RESTRICT slotAmp_dry,INT * RESTRICT slotAmp_dry_e,FIXP_DBL * RESTRICT slotAmp_wet,INT * RESTRICT slotAmp_wet_e,FIXP_DBL * RESTRICT pHybOutputRealDry,FIXP_DBL * RESTRICT pHybOutputImagDry,FIXP_DBL * RESTRICT pHybOutputRealWet,FIXP_DBL * RESTRICT pHybOutputImagWet,INT cplxBands,INT hybBands)244*e5436536SAndroid Build Coastguard Worker static inline void slotAmp(
245*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT slotAmp_dry, INT *RESTRICT slotAmp_dry_e,
246*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT slotAmp_wet, INT *RESTRICT slotAmp_wet_e,
247*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pHybOutputRealDry, FIXP_DBL *RESTRICT pHybOutputImagDry,
248*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pHybOutputRealWet, FIXP_DBL *RESTRICT pHybOutputImagWet,
249*e5436536SAndroid Build Coastguard Worker INT cplxBands, INT hybBands) {
250*e5436536SAndroid Build Coastguard Worker INT qs, s1, s2, headroom_dry, headroom_wet;
251*e5436536SAndroid Build Coastguard Worker FIXP_DBL dry, wet;
252*e5436536SAndroid Build Coastguard Worker
253*e5436536SAndroid Build Coastguard Worker /* headroom can be reduced by 1 bit due to use of fPow2Div2 */
254*e5436536SAndroid Build Coastguard Worker s1 = DFRACT_BITS - 1 - CntLeadingZeros(hybBands + cplxBands);
255*e5436536SAndroid Build Coastguard Worker headroom_dry = fMin(getScalefactor(pHybOutputRealDry, hybBands),
256*e5436536SAndroid Build Coastguard Worker getScalefactor(pHybOutputImagDry, cplxBands));
257*e5436536SAndroid Build Coastguard Worker headroom_wet = fMin(getScalefactor(pHybOutputRealWet, hybBands),
258*e5436536SAndroid Build Coastguard Worker getScalefactor(pHybOutputImagWet, cplxBands));
259*e5436536SAndroid Build Coastguard Worker
260*e5436536SAndroid Build Coastguard Worker dry = wet = FL2FXCONST_DBL(0.0f);
261*e5436536SAndroid Build Coastguard Worker for (qs = 0; qs < cplxBands; qs++) {
262*e5436536SAndroid Build Coastguard Worker /* sum up dry part */
263*e5436536SAndroid Build Coastguard Worker dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
264*e5436536SAndroid Build Coastguard Worker dry += (fPow2Div2(pHybOutputImagDry[qs] << headroom_dry) >> s1);
265*e5436536SAndroid Build Coastguard Worker /* sum up wet part */
266*e5436536SAndroid Build Coastguard Worker wet += (fPow2Div2(pHybOutputRealWet[qs] << headroom_wet) >> s1);
267*e5436536SAndroid Build Coastguard Worker wet += (fPow2Div2(pHybOutputImagWet[qs] << headroom_wet) >> s1);
268*e5436536SAndroid Build Coastguard Worker }
269*e5436536SAndroid Build Coastguard Worker for (; qs < hybBands; qs++) {
270*e5436536SAndroid Build Coastguard Worker dry += (fPow2Div2(pHybOutputRealDry[qs] << headroom_dry) >> s1);
271*e5436536SAndroid Build Coastguard Worker wet += (fPow2Div2(pHybOutputRealWet[qs] << headroom_wet) >> s1);
272*e5436536SAndroid Build Coastguard Worker }
273*e5436536SAndroid Build Coastguard Worker
274*e5436536SAndroid Build Coastguard Worker /* consider fPow2Div2() */
275*e5436536SAndroid Build Coastguard Worker s1 += 1;
276*e5436536SAndroid Build Coastguard Worker
277*e5436536SAndroid Build Coastguard Worker /* normalize dry part, ensure that exponent is even */
278*e5436536SAndroid Build Coastguard Worker s2 = fixMax(0, CntLeadingZeros(dry) - 1);
279*e5436536SAndroid Build Coastguard Worker *slotAmp_dry = dry << s2;
280*e5436536SAndroid Build Coastguard Worker *slotAmp_dry_e = s1 - s2 - 2 * headroom_dry;
281*e5436536SAndroid Build Coastguard Worker if (*slotAmp_dry_e & 1) {
282*e5436536SAndroid Build Coastguard Worker *slotAmp_dry = *slotAmp_dry >> 1;
283*e5436536SAndroid Build Coastguard Worker *slotAmp_dry_e += 1;
284*e5436536SAndroid Build Coastguard Worker }
285*e5436536SAndroid Build Coastguard Worker
286*e5436536SAndroid Build Coastguard Worker /* normalize wet part, ensure that exponent is even */
287*e5436536SAndroid Build Coastguard Worker s2 = fixMax(0, CntLeadingZeros(wet) - 1);
288*e5436536SAndroid Build Coastguard Worker *slotAmp_wet = wet << s2;
289*e5436536SAndroid Build Coastguard Worker *slotAmp_wet_e = s1 - s2 - 2 * headroom_wet;
290*e5436536SAndroid Build Coastguard Worker if (*slotAmp_wet_e & 1) {
291*e5436536SAndroid Build Coastguard Worker *slotAmp_wet = *slotAmp_wet >> 1;
292*e5436536SAndroid Build Coastguard Worker *slotAmp_wet_e += 1;
293*e5436536SAndroid Build Coastguard Worker }
294*e5436536SAndroid Build Coastguard Worker }
295*e5436536SAndroid Build Coastguard Worker
296*e5436536SAndroid Build Coastguard Worker #if defined(__aarch64__)
297*e5436536SAndroid Build Coastguard Worker __attribute__((noinline))
298*e5436536SAndroid Build Coastguard Worker #endif
299*e5436536SAndroid Build Coastguard Worker static void
shapeBBEnv(FIXP_DBL * pHybOutputRealDry,FIXP_DBL * pHybOutputImagDry,FIXP_DBL dryFac,INT scale,INT cplxBands,INT hybBands)300*e5436536SAndroid Build Coastguard Worker shapeBBEnv(FIXP_DBL *pHybOutputRealDry, FIXP_DBL *pHybOutputImagDry,
301*e5436536SAndroid Build Coastguard Worker FIXP_DBL dryFac, INT scale, INT cplxBands, INT hybBands) {
302*e5436536SAndroid Build Coastguard Worker INT qs;
303*e5436536SAndroid Build Coastguard Worker
304*e5436536SAndroid Build Coastguard Worker if (scale == 0) {
305*e5436536SAndroid Build Coastguard Worker for (qs = 0; qs < cplxBands; qs++) {
306*e5436536SAndroid Build Coastguard Worker pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac);
307*e5436536SAndroid Build Coastguard Worker pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac);
308*e5436536SAndroid Build Coastguard Worker }
309*e5436536SAndroid Build Coastguard Worker for (; qs < hybBands; qs++) {
310*e5436536SAndroid Build Coastguard Worker pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac);
311*e5436536SAndroid Build Coastguard Worker }
312*e5436536SAndroid Build Coastguard Worker } else {
313*e5436536SAndroid Build Coastguard Worker for (qs = 0; qs < cplxBands; qs++) {
314*e5436536SAndroid Build Coastguard Worker pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
315*e5436536SAndroid Build Coastguard Worker fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
316*e5436536SAndroid Build Coastguard Worker pHybOutputImagDry[qs] = SATURATE_LEFT_SHIFT(
317*e5436536SAndroid Build Coastguard Worker fMultDiv2(pHybOutputImagDry[qs], dryFac), scale, DFRACT_BITS);
318*e5436536SAndroid Build Coastguard Worker }
319*e5436536SAndroid Build Coastguard Worker for (; qs < hybBands; qs++) {
320*e5436536SAndroid Build Coastguard Worker pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT(
321*e5436536SAndroid Build Coastguard Worker fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS);
322*e5436536SAndroid Build Coastguard Worker }
323*e5436536SAndroid Build Coastguard Worker }
324*e5436536SAndroid Build Coastguard Worker }
325*e5436536SAndroid Build Coastguard Worker
extractBBEnv(spatialDec * self,INT inp,INT start,INT channels,FIXP_DBL * pEnv,const SPATIAL_BS_FRAME * frame)326*e5436536SAndroid Build Coastguard Worker static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels,
327*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pEnv, const SPATIAL_BS_FRAME *frame) {
328*e5436536SAndroid Build Coastguard Worker INT ch, pb, prevChOffs;
329*e5436536SAndroid Build Coastguard Worker INT clz, scale, scale_min, envSF;
330*e5436536SAndroid Build Coastguard Worker INT scaleCur, scalePrev, commonScale;
331*e5436536SAndroid Build Coastguard Worker INT slotNrgSF, partNrgSF, frameNrgSF;
332*e5436536SAndroid Build Coastguard Worker INT *pPartNrgPrevSF, *pFrameNrgPrevSF;
333*e5436536SAndroid Build Coastguard Worker INT *pNormNrgPrevSF, *pPartNrgPrev2SF;
334*e5436536SAndroid Build Coastguard Worker
335*e5436536SAndroid Build Coastguard Worker FIXP_DBL maxVal, env, frameNrg, normNrg;
336*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pReal, *pImag;
337*e5436536SAndroid Build Coastguard Worker FIXP_DBL *partNrg, *partNrgPrev;
338*e5436536SAndroid Build Coastguard Worker
339*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_START(pScratchBuffer, FIXP_DBL,
340*e5436536SAndroid Build Coastguard Worker (2 * 42 + MAX_PARAMETER_BANDS));
341*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_START(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV));
342*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_START(resPbSF, INT, (END_BB_ENV - START_BB_ENV));
343*e5436536SAndroid Build Coastguard Worker
344*e5436536SAndroid Build Coastguard Worker FIXP_DBL *slotNrg = pScratchBuffer + (2 * 42);
345*e5436536SAndroid Build Coastguard Worker
346*e5436536SAndroid Build Coastguard Worker RESHAPE_BBENV_STATE *pBBEnvState = self->reshapeBBEnvState;
347*e5436536SAndroid Build Coastguard Worker
348*e5436536SAndroid Build Coastguard Worker FIXP_DBL alpha = pBBEnvState->alpha__FDK;
349*e5436536SAndroid Build Coastguard Worker /*FIXP_DBL alpha1 = (FL2FXCONST_DBL(1.0f) - alpha) << SF_ALPHA1;*/
350*e5436536SAndroid Build Coastguard Worker FIXP_DBL alpha1 = ((FIXP_DBL)MAXVAL_DBL - alpha) << SF_ALPHA1;
351*e5436536SAndroid Build Coastguard Worker FIXP_DBL beta = pBBEnvState->beta__FDK;
352*e5436536SAndroid Build Coastguard Worker /*FIXP_DBL beta1 = (FL2FXCONST_DBL(1.0f) - beta) << SF_BETA1;*/
353*e5436536SAndroid Build Coastguard Worker FIXP_DBL beta1 = ((FIXP_DBL)MAXVAL_DBL - beta) << SF_BETA1;
354*e5436536SAndroid Build Coastguard Worker
355*e5436536SAndroid Build Coastguard Worker INT shapeActiv = 1;
356*e5436536SAndroid Build Coastguard Worker INT hybBands = fixMin(42, self->hybridBands);
357*e5436536SAndroid Build Coastguard Worker INT staticScale = self->staticDecScale + (1);
358*e5436536SAndroid Build Coastguard Worker INT cplxBands;
359*e5436536SAndroid Build Coastguard Worker cplxBands = fixMin(42, self->hybridBands);
360*e5436536SAndroid Build Coastguard Worker
361*e5436536SAndroid Build Coastguard Worker for (ch = start; ch < channels; ch++) {
362*e5436536SAndroid Build Coastguard Worker if (inp == INP_DRY_WET) {
363*e5436536SAndroid Build Coastguard Worker INT ch2 = row2channelGES[self->treeConfig][ch];
364*e5436536SAndroid Build Coastguard Worker if (ch2 == -1) {
365*e5436536SAndroid Build Coastguard Worker continue;
366*e5436536SAndroid Build Coastguard Worker } else {
367*e5436536SAndroid Build Coastguard Worker if (frame->tempShapeEnableChannelGES[ch2]) {
368*e5436536SAndroid Build Coastguard Worker shapeActiv = 1;
369*e5436536SAndroid Build Coastguard Worker } else {
370*e5436536SAndroid Build Coastguard Worker shapeActiv = 0;
371*e5436536SAndroid Build Coastguard Worker }
372*e5436536SAndroid Build Coastguard Worker }
373*e5436536SAndroid Build Coastguard Worker prevChOffs = ch;
374*e5436536SAndroid Build Coastguard Worker pReal = pScratchBuffer;
375*e5436536SAndroid Build Coastguard Worker pImag = pScratchBuffer + 42;
376*e5436536SAndroid Build Coastguard Worker combineDryWet(pReal, pImag, self->hybOutputRealDry__FDK[ch],
377*e5436536SAndroid Build Coastguard Worker self->hybOutputImagDry__FDK[ch],
378*e5436536SAndroid Build Coastguard Worker self->hybOutputRealWet__FDK[ch],
379*e5436536SAndroid Build Coastguard Worker self->hybOutputImagWet__FDK[ch], cplxBands, hybBands);
380*e5436536SAndroid Build Coastguard Worker clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
381*e5436536SAndroid Build Coastguard Worker getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
382*e5436536SAndroid Build Coastguard Worker } else {
383*e5436536SAndroid Build Coastguard Worker prevChOffs = ch + self->numOutputChannels;
384*e5436536SAndroid Build Coastguard Worker pReal = self->hybInputReal__FDK[ch];
385*e5436536SAndroid Build Coastguard Worker pImag = self->hybInputImag__FDK[ch];
386*e5436536SAndroid Build Coastguard Worker clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)),
387*e5436536SAndroid Build Coastguard Worker getScalefactor(&pImag[12], fMax(0, cplxBands - 12)));
388*e5436536SAndroid Build Coastguard Worker }
389*e5436536SAndroid Build Coastguard Worker
390*e5436536SAndroid Build Coastguard Worker partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs];
391*e5436536SAndroid Build Coastguard Worker pPartNrgPrevSF = &pBBEnvState->partNrgPrevSF[prevChOffs];
392*e5436536SAndroid Build Coastguard Worker pFrameNrgPrevSF = &pBBEnvState->frameNrgPrevSF[prevChOffs];
393*e5436536SAndroid Build Coastguard Worker pNormNrgPrevSF = &pBBEnvState->normNrgPrevSF[prevChOffs];
394*e5436536SAndroid Build Coastguard Worker pPartNrgPrev2SF = &pBBEnvState->partNrgPrev2SF[prevChOffs];
395*e5436536SAndroid Build Coastguard Worker
396*e5436536SAndroid Build Coastguard Worker /* calculate slot energy */
397*e5436536SAndroid Build Coastguard Worker {
398*e5436536SAndroid Build Coastguard Worker getSlotNrgHQ(&pReal[12], &pImag[12], slotNrg, clz,
399*e5436536SAndroid Build Coastguard Worker fixMin(42, self->hybridBands)); /* scale slotNrg:
400*e5436536SAndroid Build Coastguard Worker 2*(staticScale-clz) +
401*e5436536SAndroid Build Coastguard Worker SF_FACTOR_SLOT */
402*e5436536SAndroid Build Coastguard Worker }
403*e5436536SAndroid Build Coastguard Worker
404*e5436536SAndroid Build Coastguard Worker slotNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
405*e5436536SAndroid Build Coastguard Worker SF_FACTOR_SLOT;
406*e5436536SAndroid Build Coastguard Worker frameNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) +
407*e5436536SAndroid Build Coastguard Worker SF_FACTOR_SLOT;
408*e5436536SAndroid Build Coastguard Worker
409*e5436536SAndroid Build Coastguard Worker partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1,
410*e5436536SAndroid Build Coastguard Worker pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 1);
411*e5436536SAndroid Build Coastguard Worker scalePrev = fixMax(fixMin(partNrgSF - pPartNrgPrevSF[0], DFRACT_BITS - 1),
412*e5436536SAndroid Build Coastguard Worker -(DFRACT_BITS - 1));
413*e5436536SAndroid Build Coastguard Worker scaleCur =
414*e5436536SAndroid Build Coastguard Worker fixMax(fixMin(partNrgSF - slotNrgSF + SF_ALPHA1, DFRACT_BITS - 1),
415*e5436536SAndroid Build Coastguard Worker -(DFRACT_BITS - 1));
416*e5436536SAndroid Build Coastguard Worker
417*e5436536SAndroid Build Coastguard Worker maxVal = FL2FXCONST_DBL(0.0f);
418*e5436536SAndroid Build Coastguard Worker frameNrg = FL2FXCONST_DBL(0.0f);
419*e5436536SAndroid Build Coastguard Worker if ((scaleCur < 0) && (scalePrev < 0)) {
420*e5436536SAndroid Build Coastguard Worker scaleCur = -scaleCur;
421*e5436536SAndroid Build Coastguard Worker scalePrev = -scalePrev;
422*e5436536SAndroid Build Coastguard Worker for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
423*e5436536SAndroid Build Coastguard Worker partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) +
424*e5436536SAndroid Build Coastguard Worker (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev))
425*e5436536SAndroid Build Coastguard Worker << 1;
426*e5436536SAndroid Build Coastguard Worker maxVal |= partNrg[pb];
427*e5436536SAndroid Build Coastguard Worker frameNrg += slotNrg[pb] >> 3;
428*e5436536SAndroid Build Coastguard Worker }
429*e5436536SAndroid Build Coastguard Worker } else if ((scaleCur >= 0) && (scalePrev >= 0)) {
430*e5436536SAndroid Build Coastguard Worker for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
431*e5436536SAndroid Build Coastguard Worker partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) +
432*e5436536SAndroid Build Coastguard Worker (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev))
433*e5436536SAndroid Build Coastguard Worker << 1;
434*e5436536SAndroid Build Coastguard Worker maxVal |= partNrg[pb];
435*e5436536SAndroid Build Coastguard Worker frameNrg += slotNrg[pb] >> 3;
436*e5436536SAndroid Build Coastguard Worker }
437*e5436536SAndroid Build Coastguard Worker } else if ((scaleCur < 0) && (scalePrev >= 0)) {
438*e5436536SAndroid Build Coastguard Worker scaleCur = -scaleCur;
439*e5436536SAndroid Build Coastguard Worker for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
440*e5436536SAndroid Build Coastguard Worker partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) +
441*e5436536SAndroid Build Coastguard Worker (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev))
442*e5436536SAndroid Build Coastguard Worker << 1;
443*e5436536SAndroid Build Coastguard Worker maxVal |= partNrg[pb];
444*e5436536SAndroid Build Coastguard Worker frameNrg += slotNrg[pb] >> 3;
445*e5436536SAndroid Build Coastguard Worker }
446*e5436536SAndroid Build Coastguard Worker } else { /* if ( (scaleCur >= 0) && (scalePrev < 0) ) */
447*e5436536SAndroid Build Coastguard Worker scalePrev = -scalePrev;
448*e5436536SAndroid Build Coastguard Worker for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
449*e5436536SAndroid Build Coastguard Worker partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) +
450*e5436536SAndroid Build Coastguard Worker (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev))
451*e5436536SAndroid Build Coastguard Worker << 1;
452*e5436536SAndroid Build Coastguard Worker maxVal |= partNrg[pb];
453*e5436536SAndroid Build Coastguard Worker frameNrg += slotNrg[pb] >> 3;
454*e5436536SAndroid Build Coastguard Worker }
455*e5436536SAndroid Build Coastguard Worker }
456*e5436536SAndroid Build Coastguard Worker
457*e5436536SAndroid Build Coastguard Worker /* frameNrg /= (END_BB_ENV - START_BB_ENV); 0.88888888888f =
458*e5436536SAndroid Build Coastguard Worker * (1/(END_BB_ENV-START_BB_ENV)<<3; shift with 3 is compensated in loop
459*e5436536SAndroid Build Coastguard Worker * above */
460*e5436536SAndroid Build Coastguard Worker frameNrg = fMult(frameNrg, FL2FXCONST_DBL(0.88888888888f));
461*e5436536SAndroid Build Coastguard Worker
462*e5436536SAndroid Build Coastguard Worker /* store scalefactor and headroom for part nrg prev */
463*e5436536SAndroid Build Coastguard Worker pPartNrgPrevSF[0] = partNrgSF;
464*e5436536SAndroid Build Coastguard Worker pPartNrgPrev2SF[0] = fixMax(0, CntLeadingZeros(maxVal) - 1);
465*e5436536SAndroid Build Coastguard Worker
466*e5436536SAndroid Build Coastguard Worker commonScale = fixMax(frameNrgSF - SF_ALPHA1 + 1, pFrameNrgPrevSF[0] + 1);
467*e5436536SAndroid Build Coastguard Worker scalePrev = fixMin(commonScale - pFrameNrgPrevSF[0], DFRACT_BITS - 1);
468*e5436536SAndroid Build Coastguard Worker scaleCur = fixMin(commonScale - frameNrgSF + SF_ALPHA1, DFRACT_BITS - 1);
469*e5436536SAndroid Build Coastguard Worker frameNrgSF = commonScale;
470*e5436536SAndroid Build Coastguard Worker
471*e5436536SAndroid Build Coastguard Worker frameNrg = ((fMultDiv2(alpha1, frameNrg) >> scaleCur) +
472*e5436536SAndroid Build Coastguard Worker (fMultDiv2(alpha, pBBEnvState->frameNrgPrev__FDK[prevChOffs]) >>
473*e5436536SAndroid Build Coastguard Worker scalePrev))
474*e5436536SAndroid Build Coastguard Worker << 1;
475*e5436536SAndroid Build Coastguard Worker
476*e5436536SAndroid Build Coastguard Worker clz = fixMax(0, CntLeadingZeros(frameNrg) - 1);
477*e5436536SAndroid Build Coastguard Worker pBBEnvState->frameNrgPrev__FDK[prevChOffs] = frameNrg << clz;
478*e5436536SAndroid Build Coastguard Worker pFrameNrgPrevSF[0] = frameNrgSF - clz;
479*e5436536SAndroid Build Coastguard Worker
480*e5436536SAndroid Build Coastguard Worker env = FL2FXCONST_DBL(0.0f);
481*e5436536SAndroid Build Coastguard Worker scale = clz + partNrgSF - frameNrgSF;
482*e5436536SAndroid Build Coastguard Worker scale_min = DFRACT_BITS - 1;
483*e5436536SAndroid Build Coastguard Worker for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
484*e5436536SAndroid Build Coastguard Worker if ((partNrg[pb] | slotNrg[pb]) != FL2FXCONST_DBL(0.0f)) {
485*e5436536SAndroid Build Coastguard Worker INT s;
486*e5436536SAndroid Build Coastguard Worker INT sc = 0;
487*e5436536SAndroid Build Coastguard Worker INT sn = fixMax(0, CntLeadingZeros(slotNrg[pb]) - 1);
488*e5436536SAndroid Build Coastguard Worker FIXP_DBL inv_sqrt = invSqrtNorm2(partNrg[pb], &sc);
489*e5436536SAndroid Build Coastguard Worker FIXP_DBL res = fMult(slotNrg[pb] << sn, fPow2(inv_sqrt));
490*e5436536SAndroid Build Coastguard Worker
491*e5436536SAndroid Build Coastguard Worker s = fixMax(0, CntLeadingZeros(res) - 1);
492*e5436536SAndroid Build Coastguard Worker res = res << s;
493*e5436536SAndroid Build Coastguard Worker
494*e5436536SAndroid Build Coastguard Worker sc = scale - (2 * sc - sn - s);
495*e5436536SAndroid Build Coastguard Worker scale_min = fixMin(scale_min, sc);
496*e5436536SAndroid Build Coastguard Worker
497*e5436536SAndroid Build Coastguard Worker resPb[pb] = res;
498*e5436536SAndroid Build Coastguard Worker resPbSF[pb] = sc;
499*e5436536SAndroid Build Coastguard Worker } else {
500*e5436536SAndroid Build Coastguard Worker resPb[pb] = (FIXP_DBL)0;
501*e5436536SAndroid Build Coastguard Worker resPbSF[pb] = 0;
502*e5436536SAndroid Build Coastguard Worker }
503*e5436536SAndroid Build Coastguard Worker }
504*e5436536SAndroid Build Coastguard Worker
505*e5436536SAndroid Build Coastguard Worker scale_min = 4 - scale_min;
506*e5436536SAndroid Build Coastguard Worker
507*e5436536SAndroid Build Coastguard Worker for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) {
508*e5436536SAndroid Build Coastguard Worker INT sc = fixMax(fixMin(resPbSF[pb] + scale_min, DFRACT_BITS - 1),
509*e5436536SAndroid Build Coastguard Worker -(DFRACT_BITS - 1));
510*e5436536SAndroid Build Coastguard Worker
511*e5436536SAndroid Build Coastguard Worker if (sc < 0) {
512*e5436536SAndroid Build Coastguard Worker env += resPb[pb] << (-sc);
513*e5436536SAndroid Build Coastguard Worker } else {
514*e5436536SAndroid Build Coastguard Worker env += resPb[pb] >> (sc);
515*e5436536SAndroid Build Coastguard Worker }
516*e5436536SAndroid Build Coastguard Worker }
517*e5436536SAndroid Build Coastguard Worker
518*e5436536SAndroid Build Coastguard Worker env = fMultDiv2(env, pBBEnvState->frameNrgPrev__FDK[prevChOffs]);
519*e5436536SAndroid Build Coastguard Worker envSF = slotNrgSF + scale_min + 1;
520*e5436536SAndroid Build Coastguard Worker
521*e5436536SAndroid Build Coastguard Worker commonScale = fixMax(envSF - SF_BETA1 + 1, pNormNrgPrevSF[0] + 1);
522*e5436536SAndroid Build Coastguard Worker scalePrev = fixMin(commonScale - pNormNrgPrevSF[0], DFRACT_BITS - 1);
523*e5436536SAndroid Build Coastguard Worker scaleCur = fixMin(commonScale - envSF + SF_BETA1, DFRACT_BITS - 1);
524*e5436536SAndroid Build Coastguard Worker
525*e5436536SAndroid Build Coastguard Worker normNrg = ((fMultDiv2(beta1, env) >> scaleCur) +
526*e5436536SAndroid Build Coastguard Worker (fMultDiv2(beta, pBBEnvState->normNrgPrev__FDK[prevChOffs]) >>
527*e5436536SAndroid Build Coastguard Worker scalePrev))
528*e5436536SAndroid Build Coastguard Worker << 1;
529*e5436536SAndroid Build Coastguard Worker
530*e5436536SAndroid Build Coastguard Worker clz = fixMax(0, CntLeadingZeros(normNrg) - 1);
531*e5436536SAndroid Build Coastguard Worker pBBEnvState->normNrgPrev__FDK[prevChOffs] = normNrg << clz;
532*e5436536SAndroid Build Coastguard Worker pNormNrgPrevSF[0] = commonScale - clz;
533*e5436536SAndroid Build Coastguard Worker
534*e5436536SAndroid Build Coastguard Worker if (shapeActiv) {
535*e5436536SAndroid Build Coastguard Worker if ((env | normNrg) != FL2FXCONST_DBL(0.0f)) {
536*e5436536SAndroid Build Coastguard Worker INT sc, se, sn;
537*e5436536SAndroid Build Coastguard Worker se = fixMax(0, CntLeadingZeros(env) - 1);
538*e5436536SAndroid Build Coastguard Worker sc = commonScale + SF_DIV32 - envSF + se;
539*e5436536SAndroid Build Coastguard Worker env = fMult(sqrtFixp((env << se) >> (sc & 0x1)),
540*e5436536SAndroid Build Coastguard Worker invSqrtNorm2(normNrg, &sn));
541*e5436536SAndroid Build Coastguard Worker
542*e5436536SAndroid Build Coastguard Worker sc = fixMin((sc >> 1) - sn, DFRACT_BITS - 1);
543*e5436536SAndroid Build Coastguard Worker if (sc < 0) {
544*e5436536SAndroid Build Coastguard Worker env <<= (-sc);
545*e5436536SAndroid Build Coastguard Worker } else {
546*e5436536SAndroid Build Coastguard Worker env >>= (sc);
547*e5436536SAndroid Build Coastguard Worker }
548*e5436536SAndroid Build Coastguard Worker }
549*e5436536SAndroid Build Coastguard Worker /* env is scaled by SF_DIV32/2 bits */
550*e5436536SAndroid Build Coastguard Worker }
551*e5436536SAndroid Build Coastguard Worker pEnv[ch] = env;
552*e5436536SAndroid Build Coastguard Worker }
553*e5436536SAndroid Build Coastguard Worker
554*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_END(resPbSF, INT, (END_BB_ENV - START_BB_ENV));
555*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_END(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV));
556*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_END(pScratchBuffer, FIXP_DBL, (2 * 42 + MAX_PARAMETER_BANDS));
557*e5436536SAndroid Build Coastguard Worker }
558*e5436536SAndroid Build Coastguard Worker
SpatialDecReshapeBBEnv(spatialDec * self,const SPATIAL_BS_FRAME * frame,INT ts)559*e5436536SAndroid Build Coastguard Worker void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame,
560*e5436536SAndroid Build Coastguard Worker INT ts) {
561*e5436536SAndroid Build Coastguard Worker INT ch, scale;
562*e5436536SAndroid Build Coastguard Worker INT dryFacSF, slotAmpSF;
563*e5436536SAndroid Build Coastguard Worker INT slotAmp_dry_e, slotAmp_wet_e;
564*e5436536SAndroid Build Coastguard Worker FIXP_DBL tmp, dryFac, envShape;
565*e5436536SAndroid Build Coastguard Worker FIXP_DBL slotAmp_dry, slotAmp_wet, slotAmp_ratio;
566*e5436536SAndroid Build Coastguard Worker FIXP_DBL envDry[MAX_OUTPUT_CHANNELS], envDmx[2];
567*e5436536SAndroid Build Coastguard Worker
568*e5436536SAndroid Build Coastguard Worker INT cplxBands;
569*e5436536SAndroid Build Coastguard Worker INT hybBands = self->hybridBands - 6;
570*e5436536SAndroid Build Coastguard Worker
571*e5436536SAndroid Build Coastguard Worker cplxBands = self->hybridBands - 6;
572*e5436536SAndroid Build Coastguard Worker
573*e5436536SAndroid Build Coastguard Worker /* extract downmix envelope(s) */
574*e5436536SAndroid Build Coastguard Worker switch (self->treeConfig) {
575*e5436536SAndroid Build Coastguard Worker default:
576*e5436536SAndroid Build Coastguard Worker extractBBEnv(self, INP_DMX, 0, fMin(self->numInputChannels, 2), envDmx,
577*e5436536SAndroid Build Coastguard Worker frame);
578*e5436536SAndroid Build Coastguard Worker }
579*e5436536SAndroid Build Coastguard Worker
580*e5436536SAndroid Build Coastguard Worker /* extract dry and wet envelopes */
581*e5436536SAndroid Build Coastguard Worker extractBBEnv(self, INP_DRY_WET, 0, self->numOutputChannels, envDry, frame);
582*e5436536SAndroid Build Coastguard Worker
583*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < self->numOutputChannels; ch++) {
584*e5436536SAndroid Build Coastguard Worker INT ch2;
585*e5436536SAndroid Build Coastguard Worker
586*e5436536SAndroid Build Coastguard Worker ch2 = row2channelGES[self->treeConfig][ch];
587*e5436536SAndroid Build Coastguard Worker
588*e5436536SAndroid Build Coastguard Worker if (ch2 == -1) continue;
589*e5436536SAndroid Build Coastguard Worker
590*e5436536SAndroid Build Coastguard Worker if (frame->tempShapeEnableChannelGES[ch2]) {
591*e5436536SAndroid Build Coastguard Worker INT sc;
592*e5436536SAndroid Build Coastguard Worker
593*e5436536SAndroid Build Coastguard Worker /* reshape dry and wet signals according to transmitted envelope */
594*e5436536SAndroid Build Coastguard Worker
595*e5436536SAndroid Build Coastguard Worker /* De-quantize GES data */
596*e5436536SAndroid Build Coastguard Worker FDK_ASSERT((frame->bsEnvShapeData[ch2][ts] >= 0) &&
597*e5436536SAndroid Build Coastguard Worker (frame->bsEnvShapeData[ch2][ts] <= 4));
598*e5436536SAndroid Build Coastguard Worker FDK_ASSERT((self->envQuantMode == 0) || (self->envQuantMode == 1));
599*e5436536SAndroid Build Coastguard Worker envShape =
600*e5436536SAndroid Build Coastguard Worker FX_CFG2FX_DBL(envShapeDataTable__FDK[frame->bsEnvShapeData[ch2][ts]]
601*e5436536SAndroid Build Coastguard Worker [self->envQuantMode]);
602*e5436536SAndroid Build Coastguard Worker
603*e5436536SAndroid Build Coastguard Worker /* get downmix channel */
604*e5436536SAndroid Build Coastguard Worker ch2 = self->row2channelDmxGES[ch];
605*e5436536SAndroid Build Coastguard Worker
606*e5436536SAndroid Build Coastguard Worker /* multiply ratio with dmx envelope; tmp is scaled by SF_DIV32/2+SF_SHAPE
607*e5436536SAndroid Build Coastguard Worker * bits */
608*e5436536SAndroid Build Coastguard Worker if (ch2 == 2) {
609*e5436536SAndroid Build Coastguard Worker tmp = fMultDiv2(envShape, envDmx[0]) + fMultDiv2(envShape, envDmx[1]);
610*e5436536SAndroid Build Coastguard Worker } else {
611*e5436536SAndroid Build Coastguard Worker tmp = fMult(envShape, envDmx[ch2]);
612*e5436536SAndroid Build Coastguard Worker }
613*e5436536SAndroid Build Coastguard Worker
614*e5436536SAndroid Build Coastguard Worker /* weighting factors */
615*e5436536SAndroid Build Coastguard Worker dryFacSF = slotAmpSF = 0;
616*e5436536SAndroid Build Coastguard Worker dryFac = slotAmp_ratio = FL2FXCONST_DBL(0.0f);
617*e5436536SAndroid Build Coastguard Worker
618*e5436536SAndroid Build Coastguard Worker /* dryFac will be scaled by dryFacSF bits */
619*e5436536SAndroid Build Coastguard Worker if (envDry[ch] != FL2FXCONST_DBL(0.0f)) {
620*e5436536SAndroid Build Coastguard Worker envDry[ch] = invSqrtNorm2(envDry[ch], &dryFacSF);
621*e5436536SAndroid Build Coastguard Worker dryFac = fMultDiv2(tmp, fPow2Div2(envDry[ch])) << 2;
622*e5436536SAndroid Build Coastguard Worker dryFacSF = SF_SHAPE + 2 * dryFacSF;
623*e5436536SAndroid Build Coastguard Worker }
624*e5436536SAndroid Build Coastguard Worker
625*e5436536SAndroid Build Coastguard Worker slotAmp_dry_e = slotAmp_wet_e = 0;
626*e5436536SAndroid Build Coastguard Worker
627*e5436536SAndroid Build Coastguard Worker /* calculate slotAmp_dry and slotAmp_wet */
628*e5436536SAndroid Build Coastguard Worker slotAmp(&slotAmp_dry, &slotAmp_dry_e, &slotAmp_wet, &slotAmp_wet_e,
629*e5436536SAndroid Build Coastguard Worker &self->hybOutputRealDry__FDK[ch][6],
630*e5436536SAndroid Build Coastguard Worker &self->hybOutputImagDry__FDK[ch][6],
631*e5436536SAndroid Build Coastguard Worker &self->hybOutputRealWet__FDK[ch][6],
632*e5436536SAndroid Build Coastguard Worker &self->hybOutputImagWet__FDK[ch][6], cplxBands, hybBands);
633*e5436536SAndroid Build Coastguard Worker
634*e5436536SAndroid Build Coastguard Worker /* exponents must be even due to subsequent square root calculation */
635*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(((slotAmp_dry_e & 1) == 0) && ((slotAmp_wet_e & 1) == 0));
636*e5436536SAndroid Build Coastguard Worker
637*e5436536SAndroid Build Coastguard Worker /* slotAmp_ratio will be scaled by slotAmpSF bits */
638*e5436536SAndroid Build Coastguard Worker if (slotAmp_dry != FL2FXCONST_DBL(0.0f)) {
639*e5436536SAndroid Build Coastguard Worker slotAmp_wet = sqrtFixp(slotAmp_wet);
640*e5436536SAndroid Build Coastguard Worker slotAmp_dry = invSqrtNorm2(slotAmp_dry, &slotAmpSF);
641*e5436536SAndroid Build Coastguard Worker
642*e5436536SAndroid Build Coastguard Worker slotAmp_ratio = fMult(slotAmp_wet, slotAmp_dry);
643*e5436536SAndroid Build Coastguard Worker slotAmpSF = slotAmpSF + (slotAmp_wet_e >> 1) - (slotAmp_dry_e >> 1);
644*e5436536SAndroid Build Coastguard Worker }
645*e5436536SAndroid Build Coastguard Worker
646*e5436536SAndroid Build Coastguard Worker /* calculate common scale factor */
647*e5436536SAndroid Build Coastguard Worker scale =
648*e5436536SAndroid Build Coastguard Worker fixMax(3, fixMax(dryFacSF, slotAmpSF)); /* scale is at least with 3
649*e5436536SAndroid Build Coastguard Worker bits to avoid overflows
650*e5436536SAndroid Build Coastguard Worker when calculating dryFac */
651*e5436536SAndroid Build Coastguard Worker dryFac = dryFac >> fixMin(scale - dryFacSF, DFRACT_BITS - 1);
652*e5436536SAndroid Build Coastguard Worker slotAmp_ratio =
653*e5436536SAndroid Build Coastguard Worker slotAmp_ratio >> fixMin(scale - slotAmpSF, DFRACT_BITS - 1);
654*e5436536SAndroid Build Coastguard Worker
655*e5436536SAndroid Build Coastguard Worker /* limit dryFac */
656*e5436536SAndroid Build Coastguard Worker dryFac = fixMax(
657*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.25f) >> (INT)fixMin(2 * scale, DFRACT_BITS - 1),
658*e5436536SAndroid Build Coastguard Worker fMult(dryFac, slotAmp_ratio) -
659*e5436536SAndroid Build Coastguard Worker (slotAmp_ratio >> fixMin(scale, DFRACT_BITS - 1)) +
660*e5436536SAndroid Build Coastguard Worker (dryFac >> fixMin(scale, DFRACT_BITS - 1)));
661*e5436536SAndroid Build Coastguard Worker dryFac = fixMin(
662*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.50f) >> (INT)fixMin(2 * scale - 3, DFRACT_BITS - 1),
663*e5436536SAndroid Build Coastguard Worker dryFac); /* reduce shift bits by 3, because upper
664*e5436536SAndroid Build Coastguard Worker limit 4.0 is scaled with 3 bits */
665*e5436536SAndroid Build Coastguard Worker scale = 2 * scale + 1;
666*e5436536SAndroid Build Coastguard Worker
667*e5436536SAndroid Build Coastguard Worker /* improve precision for dryFac */
668*e5436536SAndroid Build Coastguard Worker sc = fixMax(0, CntLeadingZeros(dryFac) - 1);
669*e5436536SAndroid Build Coastguard Worker dryFac = dryFac << (INT)fixMin(scale, sc);
670*e5436536SAndroid Build Coastguard Worker scale = scale - fixMin(scale, sc);
671*e5436536SAndroid Build Coastguard Worker
672*e5436536SAndroid Build Coastguard Worker /* shaping */
673*e5436536SAndroid Build Coastguard Worker shapeBBEnv(&self->hybOutputRealDry__FDK[ch][6],
674*e5436536SAndroid Build Coastguard Worker &self->hybOutputImagDry__FDK[ch][6], dryFac,
675*e5436536SAndroid Build Coastguard Worker fixMin(scale, DFRACT_BITS - 1), cplxBands, hybBands);
676*e5436536SAndroid Build Coastguard Worker }
677*e5436536SAndroid Build Coastguard Worker }
678*e5436536SAndroid Build Coastguard Worker }
679