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 subband processing
100*e5436536SAndroid Build Coastguard Worker
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker
103*e5436536SAndroid Build Coastguard Worker #include "sac_stp.h"
104*e5436536SAndroid Build Coastguard Worker #include "sac_calcM1andM2.h"
105*e5436536SAndroid Build Coastguard Worker #include "sac_bitdec.h"
106*e5436536SAndroid Build Coastguard Worker #include "FDK_matrixCalloc.h"
107*e5436536SAndroid Build Coastguard Worker #include "sac_rom.h"
108*e5436536SAndroid Build Coastguard Worker
109*e5436536SAndroid Build Coastguard Worker #define SF_FREQ_DOMAIN_HEADROOM (2 * (1))
110*e5436536SAndroid Build Coastguard Worker
111*e5436536SAndroid Build Coastguard Worker #define BP_GF_START 6
112*e5436536SAndroid Build Coastguard Worker #define BP_GF_SIZE 25
113*e5436536SAndroid Build Coastguard Worker #define HP_SIZE 9
114*e5436536SAndroid Build Coastguard Worker #define STP_UPDATE_ENERGY_RATE 32
115*e5436536SAndroid Build Coastguard Worker
116*e5436536SAndroid Build Coastguard Worker #define SF_WET 5
117*e5436536SAndroid Build Coastguard Worker #define SF_DRY \
118*e5436536SAndroid Build Coastguard Worker 3 /* SF_DRY == 2 would produce good conformance test results as well */
119*e5436536SAndroid Build Coastguard Worker #define SF_DRY_NRG \
120*e5436536SAndroid Build Coastguard Worker (4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \
121*e5436536SAndroid Build Coastguard Worker i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \
122*e5436536SAndroid Build Coastguard Worker calculation needs 4 bits headroom, headroom can be reduced by 1 \
123*e5436536SAndroid Build Coastguard Worker bit due to fPow2Div2() usage */
124*e5436536SAndroid Build Coastguard Worker #define SF_WET_NRG \
125*e5436536SAndroid Build Coastguard Worker (4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \
126*e5436536SAndroid Build Coastguard Worker i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \
127*e5436536SAndroid Build Coastguard Worker calculation needs 4 bits headroom, headroom can be reduced by 1 \
128*e5436536SAndroid Build Coastguard Worker bit due to fPow2Div2() usage */
129*e5436536SAndroid Build Coastguard Worker #define SF_PRODUCT_BP_GF 13
130*e5436536SAndroid Build Coastguard Worker #define SF_PRODUCT_BP_GF_GF 26
131*e5436536SAndroid Build Coastguard Worker #define SF_SCALE 2
132*e5436536SAndroid Build Coastguard Worker
133*e5436536SAndroid Build Coastguard Worker #define SF_SCALE_LD64 FL2FXCONST_DBL(0.03125) /* LD64((1<<SF_SCALE))*/
134*e5436536SAndroid Build Coastguard Worker #define STP_LPF_COEFF1__FDK FL2FXCONST_DBL(0.950f) /* 0.95 */
135*e5436536SAndroid Build Coastguard Worker #define ONE_MINUS_STP_LPF_COEFF1__FDK FL2FXCONST_DBL(0.05f) /* 1.0 - 0.95 */
136*e5436536SAndroid Build Coastguard Worker #define STP_LPF_COEFF2__FDK FL2FXCONST_DBL(0.450f) /* 0.45 */
137*e5436536SAndroid Build Coastguard Worker #define ONE_MINUS_STP_LPF_COEFF2__FDK \
138*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(1.0f - 0.450f) /* 1.0 - 0.45 */
139*e5436536SAndroid Build Coastguard Worker #define STP_SCALE_LIMIT__FDK \
140*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(2.82f / (float)(1 << SF_SCALE)) /* scaled by SF_SCALE */
141*e5436536SAndroid Build Coastguard Worker #define ONE_DIV_STP_SCALE_LIMIT__FDK \
142*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(1.0f / 2.82f / (float)(1 << SF_SCALE)) /* scaled by SF_SCALE \
143*e5436536SAndroid Build Coastguard Worker */
144*e5436536SAndroid Build Coastguard Worker #define ABS_THR__FDK \
145*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(ABS_THR / \
146*e5436536SAndroid Build Coastguard Worker ((float)(1 << (22 + 22 - 26)))) /* scaled by 18 bits */
147*e5436536SAndroid Build Coastguard Worker #define ABS_THR2__FDK \
148*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(ABS_THR * 32.0f * 32.0f / \
149*e5436536SAndroid Build Coastguard Worker ((float)(1 << (22 + 22 - 26)))) /* scaled by 10 bits */
150*e5436536SAndroid Build Coastguard Worker #define STP_SCALE_LIMIT_HI \
151*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(3.02222222222 / (1 << SF_SCALE)) /* see 4. below */
152*e5436536SAndroid Build Coastguard Worker #define STP_SCALE_LIMIT_LO \
153*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.28289992119 / (1 << SF_SCALE)) /* see 4. below */
154*e5436536SAndroid Build Coastguard Worker #define STP_SCALE_LIMIT_HI_LD64 \
155*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.04986280452) /* see 4. below \
156*e5436536SAndroid Build Coastguard Worker */
157*e5436536SAndroid Build Coastguard Worker #define STP_SCALE_LIMIT_LO_LD64 \
158*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.05692613500) /* see 4. below \
159*e5436536SAndroid Build Coastguard Worker */
160*e5436536SAndroid Build Coastguard Worker
161*e5436536SAndroid Build Coastguard Worker /* Scale factor calculation for the diffuse signal needs adapted thresholds
162*e5436536SAndroid Build Coastguard Worker for STP_SCALE_LIMIT and 1/STP_SCALE_LIMIT:
163*e5436536SAndroid Build Coastguard Worker
164*e5436536SAndroid Build Coastguard Worker 1. scale = sqrt(DryNrg/WetNrg)
165*e5436536SAndroid Build Coastguard Worker
166*e5436536SAndroid Build Coastguard Worker 2. Damping of scale factor
167*e5436536SAndroid Build Coastguard Worker scale2 = 0.1 + 0.9 * scale
168*e5436536SAndroid Build Coastguard Worker
169*e5436536SAndroid Build Coastguard Worker 3. Limiting of scale factor
170*e5436536SAndroid Build Coastguard Worker STP_SCALE_LIMIT >= scale2 >= 1/STP_SCALE_LIMIT
171*e5436536SAndroid Build Coastguard Worker => STP_SCALE_LIMIT >= (0.1 + 0.9 * scale) >= 1/STP_SCALE_LIMIT
172*e5436536SAndroid Build Coastguard Worker => (STP_SCALE_LIMIT-0.1)/0.9 >= scale >=
173*e5436536SAndroid Build Coastguard Worker (1/STP_SCALE_LIMIT-0.1)/0.9
174*e5436536SAndroid Build Coastguard Worker
175*e5436536SAndroid Build Coastguard Worker 3. Limiting of scale factor before sqrt calculation
176*e5436536SAndroid Build Coastguard Worker ((STP_SCALE_LIMIT-0.1)/0.9)^2 >= (scale^2) >=
177*e5436536SAndroid Build Coastguard Worker ((1/STP_SCALE_LIMIT-0.1)/0.9)^2 (STP_SCALE_LIMIT_HI)^2 >= (scale^2) >=
178*e5436536SAndroid Build Coastguard Worker (STP_SCALE_LIMIT_LO)^2
179*e5436536SAndroid Build Coastguard Worker
180*e5436536SAndroid Build Coastguard Worker 4. Thresholds for limiting of scale factor
181*e5436536SAndroid Build Coastguard Worker STP_SCALE_LIMIT_HI = ((2.82-0.1)/0.9)
182*e5436536SAndroid Build Coastguard Worker STP_SCALE_LIMIT_LO = (((1.0/2.82)-0.1)/0.9)
183*e5436536SAndroid Build Coastguard Worker STP_SCALE_LIMIT_HI_LD64 = LD64(STP_SCALE_LIMIT_HI*STP_SCALE_LIMIT_HI)
184*e5436536SAndroid Build Coastguard Worker STP_SCALE_LIMIT_LO_LD64 = LD64(STP_SCALE_LIMIT_LO*STP_SCALE_LIMIT_LO)
185*e5436536SAndroid Build Coastguard Worker */
186*e5436536SAndroid Build Coastguard Worker
187*e5436536SAndroid Build Coastguard Worker #define CALC_WET_SCALE(dryIdx, wetIdx) \
188*e5436536SAndroid Build Coastguard Worker if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \
189*e5436536SAndroid Build Coastguard Worker scale[wetIdx] = STP_SCALE_LIMIT_HI; \
190*e5436536SAndroid Build Coastguard Worker } else if (DryEnerLD64[dryIdx] < \
191*e5436536SAndroid Build Coastguard Worker (WetEnerLD64[wetIdx] - STP_SCALE_LIMIT_LO_LD64)) { \
192*e5436536SAndroid Build Coastguard Worker scale[wetIdx] = STP_SCALE_LIMIT_LO; \
193*e5436536SAndroid Build Coastguard Worker } else { \
194*e5436536SAndroid Build Coastguard Worker tmp = ((DryEnerLD64[dryIdx] - WetEnerLD64[wetIdx]) >> 1) - SF_SCALE_LD64; \
195*e5436536SAndroid Build Coastguard Worker scale[wetIdx] = CalcInvLdData(tmp); \
196*e5436536SAndroid Build Coastguard Worker }
197*e5436536SAndroid Build Coastguard Worker
198*e5436536SAndroid Build Coastguard Worker struct STP_DEC {
199*e5436536SAndroid Build Coastguard Worker FIXP_DBL runDryEner[MAX_INPUT_CHANNELS];
200*e5436536SAndroid Build Coastguard Worker FIXP_DBL runWetEner[MAX_OUTPUT_CHANNELS];
201*e5436536SAndroid Build Coastguard Worker FIXP_DBL oldDryEnerLD64[MAX_INPUT_CHANNELS];
202*e5436536SAndroid Build Coastguard Worker FIXP_DBL oldWetEnerLD64[MAX_OUTPUT_CHANNELS];
203*e5436536SAndroid Build Coastguard Worker FIXP_DBL prev_tp_scale[MAX_OUTPUT_CHANNELS];
204*e5436536SAndroid Build Coastguard Worker const FIXP_CFG *BP;
205*e5436536SAndroid Build Coastguard Worker const FIXP_CFG *BP_GF;
206*e5436536SAndroid Build Coastguard Worker int update_old_ener;
207*e5436536SAndroid Build Coastguard Worker };
208*e5436536SAndroid Build Coastguard Worker
combineSignalCplx(FIXP_DBL * hybOutputRealDry,FIXP_DBL * hybOutputImagDry,FIXP_DBL * hybOutputRealWet,FIXP_DBL * hybOutputImagWet,int bands)209*e5436536SAndroid Build Coastguard Worker inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry,
210*e5436536SAndroid Build Coastguard Worker FIXP_DBL *hybOutputImagDry,
211*e5436536SAndroid Build Coastguard Worker FIXP_DBL *hybOutputRealWet,
212*e5436536SAndroid Build Coastguard Worker FIXP_DBL *hybOutputImagWet, int bands) {
213*e5436536SAndroid Build Coastguard Worker int n;
214*e5436536SAndroid Build Coastguard Worker
215*e5436536SAndroid Build Coastguard Worker for (n = bands - 1; n >= 0; n--) {
216*e5436536SAndroid Build Coastguard Worker *hybOutputRealDry = fAddSaturate(*hybOutputRealDry, *hybOutputRealWet);
217*e5436536SAndroid Build Coastguard Worker *hybOutputImagDry = fAddSaturate(*hybOutputImagDry, *hybOutputImagWet);
218*e5436536SAndroid Build Coastguard Worker hybOutputRealDry++, hybOutputRealWet++;
219*e5436536SAndroid Build Coastguard Worker hybOutputImagDry++, hybOutputImagWet++;
220*e5436536SAndroid Build Coastguard Worker }
221*e5436536SAndroid Build Coastguard Worker }
222*e5436536SAndroid Build Coastguard Worker
combineSignalCplxScale1(FIXP_DBL * hybOutputRealDry,FIXP_DBL * hybOutputImagDry,FIXP_DBL * hybOutputRealWet,FIXP_DBL * hybOutputImagWet,const FIXP_CFG * pBP,FIXP_DBL scaleX,int bands)223*e5436536SAndroid Build Coastguard Worker inline void combineSignalCplxScale1(FIXP_DBL *hybOutputRealDry,
224*e5436536SAndroid Build Coastguard Worker FIXP_DBL *hybOutputImagDry,
225*e5436536SAndroid Build Coastguard Worker FIXP_DBL *hybOutputRealWet,
226*e5436536SAndroid Build Coastguard Worker FIXP_DBL *hybOutputImagWet,
227*e5436536SAndroid Build Coastguard Worker const FIXP_CFG *pBP, FIXP_DBL scaleX,
228*e5436536SAndroid Build Coastguard Worker int bands) {
229*e5436536SAndroid Build Coastguard Worker int n;
230*e5436536SAndroid Build Coastguard Worker FIXP_DBL scaleY;
231*e5436536SAndroid Build Coastguard Worker for (n = bands - 1; n >= 0; n--) {
232*e5436536SAndroid Build Coastguard Worker scaleY = fMult(scaleX, *pBP);
233*e5436536SAndroid Build Coastguard Worker *hybOutputRealDry = SATURATE_LEFT_SHIFT(
234*e5436536SAndroid Build Coastguard Worker (*hybOutputRealDry >> SF_SCALE) + fMult(*hybOutputRealWet, scaleY),
235*e5436536SAndroid Build Coastguard Worker SF_SCALE, DFRACT_BITS);
236*e5436536SAndroid Build Coastguard Worker *hybOutputImagDry = SATURATE_LEFT_SHIFT(
237*e5436536SAndroid Build Coastguard Worker (*hybOutputImagDry >> SF_SCALE) + fMult(*hybOutputImagWet, scaleY),
238*e5436536SAndroid Build Coastguard Worker SF_SCALE, DFRACT_BITS);
239*e5436536SAndroid Build Coastguard Worker hybOutputRealDry++, hybOutputRealWet++;
240*e5436536SAndroid Build Coastguard Worker hybOutputImagDry++, hybOutputImagWet++;
241*e5436536SAndroid Build Coastguard Worker pBP++;
242*e5436536SAndroid Build Coastguard Worker }
243*e5436536SAndroid Build Coastguard Worker }
244*e5436536SAndroid Build Coastguard Worker
combineSignalCplxScale2(FIXP_DBL * hybOutputRealDry,FIXP_DBL * hybOutputImagDry,FIXP_DBL * hybOutputRealWet,FIXP_DBL * hybOutputImagWet,FIXP_DBL scaleX,int bands)245*e5436536SAndroid Build Coastguard Worker inline void combineSignalCplxScale2(FIXP_DBL *hybOutputRealDry,
246*e5436536SAndroid Build Coastguard Worker FIXP_DBL *hybOutputImagDry,
247*e5436536SAndroid Build Coastguard Worker FIXP_DBL *hybOutputRealWet,
248*e5436536SAndroid Build Coastguard Worker FIXP_DBL *hybOutputImagWet, FIXP_DBL scaleX,
249*e5436536SAndroid Build Coastguard Worker int bands) {
250*e5436536SAndroid Build Coastguard Worker int n;
251*e5436536SAndroid Build Coastguard Worker
252*e5436536SAndroid Build Coastguard Worker for (n = bands - 1; n >= 0; n--) {
253*e5436536SAndroid Build Coastguard Worker *hybOutputRealDry = SATURATE_LEFT_SHIFT(
254*e5436536SAndroid Build Coastguard Worker (*hybOutputRealDry >> SF_SCALE) + fMult(*hybOutputRealWet, scaleX),
255*e5436536SAndroid Build Coastguard Worker SF_SCALE, DFRACT_BITS);
256*e5436536SAndroid Build Coastguard Worker *hybOutputImagDry = SATURATE_LEFT_SHIFT(
257*e5436536SAndroid Build Coastguard Worker (*hybOutputImagDry >> SF_SCALE) + fMult(*hybOutputImagWet, scaleX),
258*e5436536SAndroid Build Coastguard Worker SF_SCALE, DFRACT_BITS);
259*e5436536SAndroid Build Coastguard Worker hybOutputRealDry++, hybOutputRealWet++;
260*e5436536SAndroid Build Coastguard Worker hybOutputImagDry++, hybOutputImagWet++;
261*e5436536SAndroid Build Coastguard Worker }
262*e5436536SAndroid Build Coastguard Worker }
263*e5436536SAndroid Build Coastguard Worker
264*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
265*e5436536SAndroid Build Coastguard Worker Functionname: subbandTPCreate
266*e5436536SAndroid Build Coastguard Worker ******************************************************************************/
subbandTPCreate(HANDLE_STP_DEC * hStpDec)267*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR subbandTPCreate(HANDLE_STP_DEC *hStpDec) {
268*e5436536SAndroid Build Coastguard Worker HANDLE_STP_DEC self = NULL;
269*e5436536SAndroid Build Coastguard Worker FDK_ALLOCATE_MEMORY_1D(self, 1, struct STP_DEC)
270*e5436536SAndroid Build Coastguard Worker if (hStpDec != NULL) {
271*e5436536SAndroid Build Coastguard Worker *hStpDec = self;
272*e5436536SAndroid Build Coastguard Worker }
273*e5436536SAndroid Build Coastguard Worker
274*e5436536SAndroid Build Coastguard Worker return MPS_OK;
275*e5436536SAndroid Build Coastguard Worker bail:
276*e5436536SAndroid Build Coastguard Worker return MPS_OUTOFMEMORY;
277*e5436536SAndroid Build Coastguard Worker }
278*e5436536SAndroid Build Coastguard Worker
subbandTPInit(HANDLE_STP_DEC self)279*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self) {
280*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR err = MPS_OK;
281*e5436536SAndroid Build Coastguard Worker int ch;
282*e5436536SAndroid Build Coastguard Worker
283*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) {
284*e5436536SAndroid Build Coastguard Worker self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE));
285*e5436536SAndroid Build Coastguard Worker self->oldWetEnerLD64[ch] = FL2FXCONST_DBL(0.0);
286*e5436536SAndroid Build Coastguard Worker }
287*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) {
288*e5436536SAndroid Build Coastguard Worker self->oldDryEnerLD64[ch] = FL2FXCONST_DBL(0.0);
289*e5436536SAndroid Build Coastguard Worker }
290*e5436536SAndroid Build Coastguard Worker
291*e5436536SAndroid Build Coastguard Worker self->BP = BP__FDK;
292*e5436536SAndroid Build Coastguard Worker self->BP_GF = BP_GF__FDK;
293*e5436536SAndroid Build Coastguard Worker
294*e5436536SAndroid Build Coastguard Worker self->update_old_ener = 0;
295*e5436536SAndroid Build Coastguard Worker
296*e5436536SAndroid Build Coastguard Worker return err;
297*e5436536SAndroid Build Coastguard Worker }
298*e5436536SAndroid Build Coastguard Worker
299*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
300*e5436536SAndroid Build Coastguard Worker Functionname: subbandTPDestroy
301*e5436536SAndroid Build Coastguard Worker ******************************************************************************/
subbandTPDestroy(HANDLE_STP_DEC * hStpDec)302*e5436536SAndroid Build Coastguard Worker void subbandTPDestroy(HANDLE_STP_DEC *hStpDec) {
303*e5436536SAndroid Build Coastguard Worker if (hStpDec != NULL) {
304*e5436536SAndroid Build Coastguard Worker FDK_FREE_MEMORY_1D(*hStpDec);
305*e5436536SAndroid Build Coastguard Worker }
306*e5436536SAndroid Build Coastguard Worker }
307*e5436536SAndroid Build Coastguard Worker
308*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
309*e5436536SAndroid Build Coastguard Worker Functionname: subbandTPApply
310*e5436536SAndroid Build Coastguard Worker ******************************************************************************/
subbandTPApply(spatialDec * self,const SPATIAL_BS_FRAME * frame)311*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) {
312*e5436536SAndroid Build Coastguard Worker FIXP_DBL *qmfOutputRealDry[MAX_OUTPUT_CHANNELS];
313*e5436536SAndroid Build Coastguard Worker FIXP_DBL *qmfOutputImagDry[MAX_OUTPUT_CHANNELS];
314*e5436536SAndroid Build Coastguard Worker FIXP_DBL *qmfOutputRealWet[MAX_OUTPUT_CHANNELS];
315*e5436536SAndroid Build Coastguard Worker FIXP_DBL *qmfOutputImagWet[MAX_OUTPUT_CHANNELS];
316*e5436536SAndroid Build Coastguard Worker
317*e5436536SAndroid Build Coastguard Worker FIXP_DBL DryEner[MAX_INPUT_CHANNELS];
318*e5436536SAndroid Build Coastguard Worker FIXP_DBL scale[MAX_OUTPUT_CHANNELS];
319*e5436536SAndroid Build Coastguard Worker
320*e5436536SAndroid Build Coastguard Worker FIXP_DBL DryEnerLD64[MAX_INPUT_CHANNELS];
321*e5436536SAndroid Build Coastguard Worker FIXP_DBL WetEnerLD64[MAX_OUTPUT_CHANNELS];
322*e5436536SAndroid Build Coastguard Worker
323*e5436536SAndroid Build Coastguard Worker FIXP_DBL DryEner0 = FL2FXCONST_DBL(0.0f);
324*e5436536SAndroid Build Coastguard Worker FIXP_DBL WetEnerX, damp, tmp;
325*e5436536SAndroid Build Coastguard Worker FIXP_DBL dmxReal0, dmxImag0;
326*e5436536SAndroid Build Coastguard Worker int skipChannels[MAX_OUTPUT_CHANNELS];
327*e5436536SAndroid Build Coastguard Worker int n, ch, cplxBands, cplxHybBands;
328*e5436536SAndroid Build Coastguard Worker int dry_scale_dmx, wet_scale_dmx;
329*e5436536SAndroid Build Coastguard Worker int i_LF, i_RF;
330*e5436536SAndroid Build Coastguard Worker HANDLE_STP_DEC hStpDec;
331*e5436536SAndroid Build Coastguard Worker const FIXP_CFG *pBP;
332*e5436536SAndroid Build Coastguard Worker
333*e5436536SAndroid Build Coastguard Worker int nrgScale = (2 * self->clipProtectGainSF__FDK);
334*e5436536SAndroid Build Coastguard Worker
335*e5436536SAndroid Build Coastguard Worker hStpDec = self->hStpDec;
336*e5436536SAndroid Build Coastguard Worker
337*e5436536SAndroid Build Coastguard Worker /* set scalefactor and loop counter */
338*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(SF_DRY >= 1);
339*e5436536SAndroid Build Coastguard Worker {
340*e5436536SAndroid Build Coastguard Worker cplxBands = BP_GF_SIZE;
341*e5436536SAndroid Build Coastguard Worker cplxHybBands = self->hybridBands;
342*e5436536SAndroid Build Coastguard Worker if (self->treeConfig == TREE_212) {
343*e5436536SAndroid Build Coastguard Worker dry_scale_dmx = 2; /* 2 bits to compensate fMultDiv2() and fPow2Div2()
344*e5436536SAndroid Build Coastguard Worker used in energy calculation */
345*e5436536SAndroid Build Coastguard Worker } else {
346*e5436536SAndroid Build Coastguard Worker dry_scale_dmx = (2 * SF_DRY) - 2;
347*e5436536SAndroid Build Coastguard Worker }
348*e5436536SAndroid Build Coastguard Worker wet_scale_dmx = 2;
349*e5436536SAndroid Build Coastguard Worker }
350*e5436536SAndroid Build Coastguard Worker
351*e5436536SAndroid Build Coastguard Worker /* setup pointer for forming the direct downmix signal */
352*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < self->numOutputChannels; ch++) {
353*e5436536SAndroid Build Coastguard Worker qmfOutputRealDry[ch] = &self->hybOutputRealDry__FDK[ch][7];
354*e5436536SAndroid Build Coastguard Worker qmfOutputRealWet[ch] = &self->hybOutputRealWet__FDK[ch][7];
355*e5436536SAndroid Build Coastguard Worker qmfOutputImagDry[ch] = &self->hybOutputImagDry__FDK[ch][7];
356*e5436536SAndroid Build Coastguard Worker qmfOutputImagWet[ch] = &self->hybOutputImagWet__FDK[ch][7];
357*e5436536SAndroid Build Coastguard Worker }
358*e5436536SAndroid Build Coastguard Worker
359*e5436536SAndroid Build Coastguard Worker /* clear skipping flag for all output channels */
360*e5436536SAndroid Build Coastguard Worker FDKmemset(skipChannels, 0, self->numOutputChannels * sizeof(int));
361*e5436536SAndroid Build Coastguard Worker
362*e5436536SAndroid Build Coastguard Worker /* set scale values to zero */
363*e5436536SAndroid Build Coastguard Worker FDKmemset(scale, 0, self->numOutputChannels * sizeof(FIXP_DBL));
364*e5436536SAndroid Build Coastguard Worker
365*e5436536SAndroid Build Coastguard Worker /* update normalisation energy with latest smoothed energy */
366*e5436536SAndroid Build Coastguard Worker if (hStpDec->update_old_ener == STP_UPDATE_ENERGY_RATE) {
367*e5436536SAndroid Build Coastguard Worker hStpDec->update_old_ener = 1;
368*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < self->numInputChannels; ch++) {
369*e5436536SAndroid Build Coastguard Worker hStpDec->oldDryEnerLD64[ch] =
370*e5436536SAndroid Build Coastguard Worker CalcLdData(fAddSaturate(hStpDec->runDryEner[ch], ABS_THR__FDK));
371*e5436536SAndroid Build Coastguard Worker }
372*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < self->numOutputChannels; ch++) {
373*e5436536SAndroid Build Coastguard Worker if (self->treeConfig == TREE_212)
374*e5436536SAndroid Build Coastguard Worker hStpDec->oldWetEnerLD64[ch] =
375*e5436536SAndroid Build Coastguard Worker CalcLdData(fAddSaturate(hStpDec->runWetEner[ch], ABS_THR__FDK));
376*e5436536SAndroid Build Coastguard Worker else
377*e5436536SAndroid Build Coastguard Worker hStpDec->oldWetEnerLD64[ch] =
378*e5436536SAndroid Build Coastguard Worker CalcLdData(fAddSaturate(hStpDec->runWetEner[ch], ABS_THR2__FDK));
379*e5436536SAndroid Build Coastguard Worker }
380*e5436536SAndroid Build Coastguard Worker } else {
381*e5436536SAndroid Build Coastguard Worker hStpDec->update_old_ener++;
382*e5436536SAndroid Build Coastguard Worker }
383*e5436536SAndroid Build Coastguard Worker
384*e5436536SAndroid Build Coastguard Worker /* get channel configuration */
385*e5436536SAndroid Build Coastguard Worker switch (self->treeConfig) {
386*e5436536SAndroid Build Coastguard Worker case TREE_212:
387*e5436536SAndroid Build Coastguard Worker i_LF = 0;
388*e5436536SAndroid Build Coastguard Worker i_RF = 1;
389*e5436536SAndroid Build Coastguard Worker break;
390*e5436536SAndroid Build Coastguard Worker default:
391*e5436536SAndroid Build Coastguard Worker return MPS_WRONG_TREECONFIG;
392*e5436536SAndroid Build Coastguard Worker }
393*e5436536SAndroid Build Coastguard Worker
394*e5436536SAndroid Build Coastguard Worker /* form the 'direct' downmix signal */
395*e5436536SAndroid Build Coastguard Worker pBP = hStpDec->BP_GF - BP_GF_START;
396*e5436536SAndroid Build Coastguard Worker switch (self->treeConfig) {
397*e5436536SAndroid Build Coastguard Worker case TREE_212:
398*e5436536SAndroid Build Coastguard Worker INT sMin, sNorm, sReal, sImag;
399*e5436536SAndroid Build Coastguard Worker
400*e5436536SAndroid Build Coastguard Worker sReal = fMin(getScalefactor(&qmfOutputRealDry[i_LF][BP_GF_START],
401*e5436536SAndroid Build Coastguard Worker cplxBands - BP_GF_START),
402*e5436536SAndroid Build Coastguard Worker getScalefactor(&qmfOutputRealDry[i_RF][BP_GF_START],
403*e5436536SAndroid Build Coastguard Worker cplxBands - BP_GF_START));
404*e5436536SAndroid Build Coastguard Worker sImag = fMin(getScalefactor(&qmfOutputImagDry[i_LF][BP_GF_START],
405*e5436536SAndroid Build Coastguard Worker cplxBands - BP_GF_START),
406*e5436536SAndroid Build Coastguard Worker getScalefactor(&qmfOutputImagDry[i_RF][BP_GF_START],
407*e5436536SAndroid Build Coastguard Worker cplxBands - BP_GF_START));
408*e5436536SAndroid Build Coastguard Worker sMin = fMin(sReal, sImag) - 1;
409*e5436536SAndroid Build Coastguard Worker
410*e5436536SAndroid Build Coastguard Worker for (n = BP_GF_START; n < cplxBands; n++) {
411*e5436536SAndroid Build Coastguard Worker dmxReal0 = scaleValue(qmfOutputRealDry[i_LF][n], sMin) +
412*e5436536SAndroid Build Coastguard Worker scaleValue(qmfOutputRealDry[i_RF][n], sMin);
413*e5436536SAndroid Build Coastguard Worker dmxImag0 = scaleValue(qmfOutputImagDry[i_LF][n], sMin) +
414*e5436536SAndroid Build Coastguard Worker scaleValue(qmfOutputImagDry[i_RF][n], sMin);
415*e5436536SAndroid Build Coastguard Worker
416*e5436536SAndroid Build Coastguard Worker DryEner0 += (fMultDiv2(fPow2Div2(dmxReal0), pBP[n]) +
417*e5436536SAndroid Build Coastguard Worker fMultDiv2(fPow2Div2(dmxImag0), pBP[n])) >>
418*e5436536SAndroid Build Coastguard Worker SF_DRY_NRG;
419*e5436536SAndroid Build Coastguard Worker }
420*e5436536SAndroid Build Coastguard Worker
421*e5436536SAndroid Build Coastguard Worker sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_DRY_NRG + dry_scale_dmx -
422*e5436536SAndroid Build Coastguard Worker (2 * sMin) + nrgScale;
423*e5436536SAndroid Build Coastguard Worker DryEner0 = scaleValueSaturate(
424*e5436536SAndroid Build Coastguard Worker DryEner0, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
425*e5436536SAndroid Build Coastguard Worker break;
426*e5436536SAndroid Build Coastguard Worker default:;
427*e5436536SAndroid Build Coastguard Worker }
428*e5436536SAndroid Build Coastguard Worker DryEner[0] = DryEner0;
429*e5436536SAndroid Build Coastguard Worker
430*e5436536SAndroid Build Coastguard Worker /* normalise the 'direct' signals */
431*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < self->numInputChannels; ch++) {
432*e5436536SAndroid Build Coastguard Worker if (self->treeConfig != TREE_212) DryEner[ch] = DryEner[ch] << nrgScale;
433*e5436536SAndroid Build Coastguard Worker hStpDec->runDryEner[ch] =
434*e5436536SAndroid Build Coastguard Worker fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) +
435*e5436536SAndroid Build Coastguard Worker fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]);
436*e5436536SAndroid Build Coastguard Worker if (DryEner[ch] != FL2FXCONST_DBL(0.0f)) {
437*e5436536SAndroid Build Coastguard Worker DryEnerLD64[ch] =
438*e5436536SAndroid Build Coastguard Worker fixMax((CalcLdData(DryEner[ch]) - hStpDec->oldDryEnerLD64[ch]),
439*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(-0.484375f));
440*e5436536SAndroid Build Coastguard Worker } else {
441*e5436536SAndroid Build Coastguard Worker DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
442*e5436536SAndroid Build Coastguard Worker }
443*e5436536SAndroid Build Coastguard Worker }
444*e5436536SAndroid Build Coastguard Worker for (; ch < MAX_INPUT_CHANNELS; ch++) {
445*e5436536SAndroid Build Coastguard Worker DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
446*e5436536SAndroid Build Coastguard Worker }
447*e5436536SAndroid Build Coastguard Worker
448*e5436536SAndroid Build Coastguard Worker /* normalise the 'diffuse' signals */
449*e5436536SAndroid Build Coastguard Worker pBP = hStpDec->BP_GF - BP_GF_START;
450*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < self->numOutputChannels; ch++) {
451*e5436536SAndroid Build Coastguard Worker if (skipChannels[ch]) {
452*e5436536SAndroid Build Coastguard Worker continue;
453*e5436536SAndroid Build Coastguard Worker }
454*e5436536SAndroid Build Coastguard Worker
455*e5436536SAndroid Build Coastguard Worker WetEnerX = FL2FXCONST_DBL(0.0f);
456*e5436536SAndroid Build Coastguard Worker
457*e5436536SAndroid Build Coastguard Worker if (self->treeConfig == TREE_212) {
458*e5436536SAndroid Build Coastguard Worker INT sMin, sNorm;
459*e5436536SAndroid Build Coastguard Worker
460*e5436536SAndroid Build Coastguard Worker sMin = fMin(getScalefactor(&qmfOutputRealWet[ch][BP_GF_START],
461*e5436536SAndroid Build Coastguard Worker cplxBands - BP_GF_START),
462*e5436536SAndroid Build Coastguard Worker getScalefactor(&qmfOutputImagWet[ch][BP_GF_START],
463*e5436536SAndroid Build Coastguard Worker cplxBands - BP_GF_START));
464*e5436536SAndroid Build Coastguard Worker
465*e5436536SAndroid Build Coastguard Worker for (n = BP_GF_START; n < cplxBands; n++) {
466*e5436536SAndroid Build Coastguard Worker WetEnerX +=
467*e5436536SAndroid Build Coastguard Worker (fMultDiv2(fPow2Div2(scaleValue(qmfOutputRealWet[ch][n], sMin)),
468*e5436536SAndroid Build Coastguard Worker pBP[n]) +
469*e5436536SAndroid Build Coastguard Worker fMultDiv2(fPow2Div2(scaleValue(qmfOutputImagWet[ch][n], sMin)),
470*e5436536SAndroid Build Coastguard Worker pBP[n])) >>
471*e5436536SAndroid Build Coastguard Worker SF_WET_NRG;
472*e5436536SAndroid Build Coastguard Worker }
473*e5436536SAndroid Build Coastguard Worker sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_WET_NRG + wet_scale_dmx -
474*e5436536SAndroid Build Coastguard Worker (2 * sMin) + nrgScale;
475*e5436536SAndroid Build Coastguard Worker WetEnerX = scaleValueSaturate(
476*e5436536SAndroid Build Coastguard Worker WetEnerX, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1)));
477*e5436536SAndroid Build Coastguard Worker } else
478*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(self->treeConfig == TREE_212);
479*e5436536SAndroid Build Coastguard Worker
480*e5436536SAndroid Build Coastguard Worker hStpDec->runWetEner[ch] =
481*e5436536SAndroid Build Coastguard Worker fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) +
482*e5436536SAndroid Build Coastguard Worker fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX);
483*e5436536SAndroid Build Coastguard Worker
484*e5436536SAndroid Build Coastguard Worker if (WetEnerX == FL2FXCONST_DBL(0.0f)) {
485*e5436536SAndroid Build Coastguard Worker WetEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f);
486*e5436536SAndroid Build Coastguard Worker } else {
487*e5436536SAndroid Build Coastguard Worker WetEnerLD64[ch] =
488*e5436536SAndroid Build Coastguard Worker fixMax((CalcLdData(WetEnerX) - hStpDec->oldWetEnerLD64[ch]),
489*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(-0.484375f));
490*e5436536SAndroid Build Coastguard Worker }
491*e5436536SAndroid Build Coastguard Worker }
492*e5436536SAndroid Build Coastguard Worker
493*e5436536SAndroid Build Coastguard Worker /* compute scale factor for the 'diffuse' signals */
494*e5436536SAndroid Build Coastguard Worker switch (self->treeConfig) {
495*e5436536SAndroid Build Coastguard Worker case TREE_212:
496*e5436536SAndroid Build Coastguard Worker if (DryEner[0] != FL2FXCONST_DBL(0.0f)) {
497*e5436536SAndroid Build Coastguard Worker CALC_WET_SCALE(0, i_LF);
498*e5436536SAndroid Build Coastguard Worker CALC_WET_SCALE(0, i_RF);
499*e5436536SAndroid Build Coastguard Worker }
500*e5436536SAndroid Build Coastguard Worker break;
501*e5436536SAndroid Build Coastguard Worker default:;
502*e5436536SAndroid Build Coastguard Worker }
503*e5436536SAndroid Build Coastguard Worker
504*e5436536SAndroid Build Coastguard Worker damp = FL2FXCONST_DBL(0.1f / (1 << SF_SCALE));
505*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < self->numOutputChannels; ch++) {
506*e5436536SAndroid Build Coastguard Worker /* damp the scaling factor */
507*e5436536SAndroid Build Coastguard Worker scale[ch] = damp + fMult(FL2FXCONST_DBL(0.9f), scale[ch]);
508*e5436536SAndroid Build Coastguard Worker
509*e5436536SAndroid Build Coastguard Worker /* limiting the scale factor */
510*e5436536SAndroid Build Coastguard Worker if (scale[ch] > STP_SCALE_LIMIT__FDK) {
511*e5436536SAndroid Build Coastguard Worker scale[ch] = STP_SCALE_LIMIT__FDK;
512*e5436536SAndroid Build Coastguard Worker }
513*e5436536SAndroid Build Coastguard Worker if (scale[ch] < ONE_DIV_STP_SCALE_LIMIT__FDK) {
514*e5436536SAndroid Build Coastguard Worker scale[ch] = ONE_DIV_STP_SCALE_LIMIT__FDK;
515*e5436536SAndroid Build Coastguard Worker }
516*e5436536SAndroid Build Coastguard Worker
517*e5436536SAndroid Build Coastguard Worker /* low pass filter the scaling factor */
518*e5436536SAndroid Build Coastguard Worker scale[ch] =
519*e5436536SAndroid Build Coastguard Worker fMult(STP_LPF_COEFF2__FDK, scale[ch]) +
520*e5436536SAndroid Build Coastguard Worker fMult(ONE_MINUS_STP_LPF_COEFF2__FDK, hStpDec->prev_tp_scale[ch]);
521*e5436536SAndroid Build Coastguard Worker hStpDec->prev_tp_scale[ch] = scale[ch];
522*e5436536SAndroid Build Coastguard Worker }
523*e5436536SAndroid Build Coastguard Worker
524*e5436536SAndroid Build Coastguard Worker /* combine 'direct' and scaled 'diffuse' signal */
525*e5436536SAndroid Build Coastguard Worker FDK_ASSERT((HP_SIZE - 3 + 10 - 1) == PC_NUM_HYB_BANDS);
526*e5436536SAndroid Build Coastguard Worker const SCHAR *channlIndex = row2channelSTP[self->treeConfig];
527*e5436536SAndroid Build Coastguard Worker
528*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < self->numOutputChannels; ch++) {
529*e5436536SAndroid Build Coastguard Worker int no_scaling;
530*e5436536SAndroid Build Coastguard Worker
531*e5436536SAndroid Build Coastguard Worker no_scaling = !frame->tempShapeEnableChannelSTP[channlIndex[ch]];
532*e5436536SAndroid Build Coastguard Worker if (no_scaling) {
533*e5436536SAndroid Build Coastguard Worker combineSignalCplx(
534*e5436536SAndroid Build Coastguard Worker &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder],
535*e5436536SAndroid Build Coastguard Worker &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder],
536*e5436536SAndroid Build Coastguard Worker &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder],
537*e5436536SAndroid Build Coastguard Worker &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder],
538*e5436536SAndroid Build Coastguard Worker cplxHybBands - self->tp_hybBandBorder);
539*e5436536SAndroid Build Coastguard Worker
540*e5436536SAndroid Build Coastguard Worker } else {
541*e5436536SAndroid Build Coastguard Worker FIXP_DBL scaleX;
542*e5436536SAndroid Build Coastguard Worker scaleX = scale[ch];
543*e5436536SAndroid Build Coastguard Worker pBP = hStpDec->BP - self->tp_hybBandBorder;
544*e5436536SAndroid Build Coastguard Worker /* Band[HP_SIZE-3+10-1] needs not to be processed in
545*e5436536SAndroid Build Coastguard Worker combineSignalCplxScale1(), because pB[HP_SIZE-3+10-1] would be 1.0 */
546*e5436536SAndroid Build Coastguard Worker combineSignalCplxScale1(
547*e5436536SAndroid Build Coastguard Worker &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder],
548*e5436536SAndroid Build Coastguard Worker &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder],
549*e5436536SAndroid Build Coastguard Worker &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder],
550*e5436536SAndroid Build Coastguard Worker &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder],
551*e5436536SAndroid Build Coastguard Worker &pBP[self->tp_hybBandBorder], scaleX,
552*e5436536SAndroid Build Coastguard Worker (HP_SIZE - 3 + 10 - 1) - self->tp_hybBandBorder);
553*e5436536SAndroid Build Coastguard Worker
554*e5436536SAndroid Build Coastguard Worker {
555*e5436536SAndroid Build Coastguard Worker combineSignalCplxScale2(
556*e5436536SAndroid Build Coastguard Worker &self->hybOutputRealDry__FDK[ch][HP_SIZE - 3 + 10 - 1],
557*e5436536SAndroid Build Coastguard Worker &self->hybOutputImagDry__FDK[ch][HP_SIZE - 3 + 10 - 1],
558*e5436536SAndroid Build Coastguard Worker &self->hybOutputRealWet__FDK[ch][HP_SIZE - 3 + 10 - 1],
559*e5436536SAndroid Build Coastguard Worker &self->hybOutputImagWet__FDK[ch][HP_SIZE - 3 + 10 - 1], scaleX,
560*e5436536SAndroid Build Coastguard Worker cplxHybBands - (HP_SIZE - 3 + 10 - 1));
561*e5436536SAndroid Build Coastguard Worker }
562*e5436536SAndroid Build Coastguard Worker }
563*e5436536SAndroid Build Coastguard Worker }
564*e5436536SAndroid Build Coastguard Worker
565*e5436536SAndroid Build Coastguard Worker return (SACDEC_ERROR)MPS_OK;
566*e5436536SAndroid Build Coastguard Worker ;
567*e5436536SAndroid Build Coastguard Worker }
568