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 Processing
100*e5436536SAndroid Build Coastguard Worker
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker
103*e5436536SAndroid Build Coastguard Worker /* data structures and interfaces for spatial audio reference software */
104*e5436536SAndroid Build Coastguard Worker #include "sac_process.h"
105*e5436536SAndroid Build Coastguard Worker
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_smoothing.h"
109*e5436536SAndroid Build Coastguard Worker #include "sac_rom.h"
110*e5436536SAndroid Build Coastguard Worker
111*e5436536SAndroid Build Coastguard Worker #include "sac_dec_errorcodes.h"
112*e5436536SAndroid Build Coastguard Worker
113*e5436536SAndroid Build Coastguard Worker #include "FDK_trigFcts.h"
114*e5436536SAndroid Build Coastguard Worker #include "FDK_decorrelate.h"
115*e5436536SAndroid Build Coastguard Worker
116*e5436536SAndroid Build Coastguard Worker #define SAC_DEC_APPLY_M2_SCALE(spec, s) ((spec) >> (-(s)))
117*e5436536SAndroid Build Coastguard Worker
118*e5436536SAndroid Build Coastguard Worker /**
119*e5436536SAndroid Build Coastguard Worker * \brief Linear interpolation between two parameter values.
120*e5436536SAndroid Build Coastguard Worker * a*alpha + b*(1-alpha)
121*e5436536SAndroid Build Coastguard Worker * = a*alpha + b - b*alpha
122*e5436536SAndroid Build Coastguard Worker *
123*e5436536SAndroid Build Coastguard Worker * \param alpha Weighting factor.
124*e5436536SAndroid Build Coastguard Worker * \param a Parameter a.
125*e5436536SAndroid Build Coastguard Worker * \param b Parameter b.
126*e5436536SAndroid Build Coastguard Worker *
127*e5436536SAndroid Build Coastguard Worker * \return Interpolated parameter value.
128*e5436536SAndroid Build Coastguard Worker */
interpolateParameter(const FIXP_SGL alpha,const FIXP_DBL a,const FIXP_DBL b)129*e5436536SAndroid Build Coastguard Worker FDK_INLINE FIXP_DBL interpolateParameter(const FIXP_SGL alpha, const FIXP_DBL a,
130*e5436536SAndroid Build Coastguard Worker const FIXP_DBL b) {
131*e5436536SAndroid Build Coastguard Worker return (b - fMult(alpha, b) + fMult(alpha, a));
132*e5436536SAndroid Build Coastguard Worker }
133*e5436536SAndroid Build Coastguard Worker
134*e5436536SAndroid Build Coastguard Worker /**
135*e5436536SAndroid Build Coastguard Worker * \brief Map MPEG Surround channel indices to MPEG 4 PCE like channel indices.
136*e5436536SAndroid Build Coastguard Worker * \param self Spatial decoder handle.
137*e5436536SAndroid Build Coastguard Worker * \param ch MPEG Surround channel index.
138*e5436536SAndroid Build Coastguard Worker * \return MPEG 4 PCE style channel index, corresponding to the given MPEG
139*e5436536SAndroid Build Coastguard Worker * Surround channel index.
140*e5436536SAndroid Build Coastguard Worker */
mapChannel(spatialDec * self,UINT ch)141*e5436536SAndroid Build Coastguard Worker static UINT mapChannel(spatialDec *self, UINT ch) {
142*e5436536SAndroid Build Coastguard Worker static const UCHAR chanelIdx[][8] = {
143*e5436536SAndroid Build Coastguard Worker {0, 1, 2, 3, 4, 5, 6, 7}, /* binaural, TREE_212, arbitrary tree */
144*e5436536SAndroid Build Coastguard Worker };
145*e5436536SAndroid Build Coastguard Worker
146*e5436536SAndroid Build Coastguard Worker int idx = 0;
147*e5436536SAndroid Build Coastguard Worker
148*e5436536SAndroid Build Coastguard Worker return (chanelIdx[idx][ch]);
149*e5436536SAndroid Build Coastguard Worker }
150*e5436536SAndroid Build Coastguard Worker
getChGain(spatialDec * self,UINT ch,INT * scale)151*e5436536SAndroid Build Coastguard Worker FIXP_DBL getChGain(spatialDec *self, UINT ch, INT *scale) {
152*e5436536SAndroid Build Coastguard Worker /* init no gain modifier */
153*e5436536SAndroid Build Coastguard Worker FIXP_DBL gain = 0x80000000;
154*e5436536SAndroid Build Coastguard Worker *scale = 0;
155*e5436536SAndroid Build Coastguard Worker
156*e5436536SAndroid Build Coastguard Worker if ((!isTwoChMode(self->upmixType)) &&
157*e5436536SAndroid Build Coastguard Worker (self->upmixType != UPMIXTYPE_BYPASS)) {
158*e5436536SAndroid Build Coastguard Worker if ((ch == 0) || (ch == 1) || (ch == 2)) {
159*e5436536SAndroid Build Coastguard Worker /* no modifier */
160*e5436536SAndroid Build Coastguard Worker }
161*e5436536SAndroid Build Coastguard Worker }
162*e5436536SAndroid Build Coastguard Worker
163*e5436536SAndroid Build Coastguard Worker return gain;
164*e5436536SAndroid Build Coastguard Worker }
165*e5436536SAndroid Build Coastguard Worker
SpatialDecQMFAnalysis(spatialDec * self,const PCM_MPS * inData,const INT ts,const INT bypassMode,FIXP_DBL ** qmfReal,FIXP_DBL ** qmfImag,const int numInputChannels)166*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecQMFAnalysis(spatialDec *self, const PCM_MPS *inData,
167*e5436536SAndroid Build Coastguard Worker const INT ts, const INT bypassMode,
168*e5436536SAndroid Build Coastguard Worker FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
169*e5436536SAndroid Build Coastguard Worker const int numInputChannels) {
170*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR err = MPS_OK;
171*e5436536SAndroid Build Coastguard Worker int ch, offset;
172*e5436536SAndroid Build Coastguard Worker
173*e5436536SAndroid Build Coastguard Worker offset = self->pQmfDomain->globalConf.nBandsSynthesis *
174*e5436536SAndroid Build Coastguard Worker self->pQmfDomain->globalConf.nQmfTimeSlots;
175*e5436536SAndroid Build Coastguard Worker
176*e5436536SAndroid Build Coastguard Worker {
177*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < numInputChannels; ch++) {
178*e5436536SAndroid Build Coastguard Worker const PCM_MPS *inSamples =
179*e5436536SAndroid Build Coastguard Worker &inData[ts * self->pQmfDomain->globalConf.nBandsAnalysis];
180*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pQmfRealAnalysis = qmfReal[ch]; /* no delay in blind mode */
181*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pQmfImagAnalysis = qmfImag[ch];
182*e5436536SAndroid Build Coastguard Worker
183*e5436536SAndroid Build Coastguard Worker CalculateSpaceAnalysisQmf(&self->pQmfDomain->QmfDomainIn[ch].fb,
184*e5436536SAndroid Build Coastguard Worker inSamples + (ch * offset), pQmfRealAnalysis,
185*e5436536SAndroid Build Coastguard Worker pQmfImagAnalysis);
186*e5436536SAndroid Build Coastguard Worker
187*e5436536SAndroid Build Coastguard Worker if (!isTwoChMode(self->upmixType) && !bypassMode) {
188*e5436536SAndroid Build Coastguard Worker int i;
189*e5436536SAndroid Build Coastguard Worker for (i = 0; i < self->qmfBands; i++) {
190*e5436536SAndroid Build Coastguard Worker qmfReal[ch][i] = fMult(
191*e5436536SAndroid Build Coastguard Worker scaleValueSaturate(qmfReal[ch][i], self->sacInDataHeadroom - (1)),
192*e5436536SAndroid Build Coastguard Worker self->clipProtectGain__FDK);
193*e5436536SAndroid Build Coastguard Worker qmfImag[ch][i] = fMult(
194*e5436536SAndroid Build Coastguard Worker scaleValueSaturate(qmfImag[ch][i], self->sacInDataHeadroom - (1)),
195*e5436536SAndroid Build Coastguard Worker self->clipProtectGain__FDK);
196*e5436536SAndroid Build Coastguard Worker }
197*e5436536SAndroid Build Coastguard Worker }
198*e5436536SAndroid Build Coastguard Worker }
199*e5436536SAndroid Build Coastguard Worker }
200*e5436536SAndroid Build Coastguard Worker
201*e5436536SAndroid Build Coastguard Worker self->qmfInputDelayBufPos =
202*e5436536SAndroid Build Coastguard Worker (self->qmfInputDelayBufPos + 1) % self->pc_filterdelay;
203*e5436536SAndroid Build Coastguard Worker
204*e5436536SAndroid Build Coastguard Worker return err;
205*e5436536SAndroid Build Coastguard Worker }
206*e5436536SAndroid Build Coastguard Worker
SpatialDecFeedQMF(spatialDec * self,FIXP_DBL ** qmfInDataReal,FIXP_DBL ** qmfInDataImag,const INT ts,const INT bypassMode,FIXP_DBL ** qmfReal__FDK,FIXP_DBL ** qmfImag__FDK,const INT numInputChannels)207*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecFeedQMF(spatialDec *self, FIXP_DBL **qmfInDataReal,
208*e5436536SAndroid Build Coastguard Worker FIXP_DBL **qmfInDataImag, const INT ts,
209*e5436536SAndroid Build Coastguard Worker const INT bypassMode, FIXP_DBL **qmfReal__FDK,
210*e5436536SAndroid Build Coastguard Worker FIXP_DBL **qmfImag__FDK,
211*e5436536SAndroid Build Coastguard Worker const INT numInputChannels) {
212*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR err = MPS_OK;
213*e5436536SAndroid Build Coastguard Worker int ch;
214*e5436536SAndroid Build Coastguard Worker
215*e5436536SAndroid Build Coastguard Worker {
216*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < numInputChannels; ch++) {
217*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pQmfRealAnalysis =
218*e5436536SAndroid Build Coastguard Worker qmfReal__FDK[ch]; /* no delay in blind mode */
219*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pQmfImagAnalysis = qmfImag__FDK[ch];
220*e5436536SAndroid Build Coastguard Worker
221*e5436536SAndroid Build Coastguard Worker /* Write Input data to pQmfRealAnalysis. */
222*e5436536SAndroid Build Coastguard Worker if (self->bShareDelayWithSBR) {
223*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch],
224*e5436536SAndroid Build Coastguard Worker ts + HYBRID_FILTER_DELAY, 0,
225*e5436536SAndroid Build Coastguard Worker MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis,
226*e5436536SAndroid Build Coastguard Worker pQmfImagAnalysis, 15 + (1));
227*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts,
228*e5436536SAndroid Build Coastguard Worker MAX_QMF_BANDS_TO_HYBRID, self->qmfBands,
229*e5436536SAndroid Build Coastguard Worker pQmfRealAnalysis, pQmfImagAnalysis, 15 + (1));
230*e5436536SAndroid Build Coastguard Worker } else {
231*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts, 0,
232*e5436536SAndroid Build Coastguard Worker self->qmfBands, pQmfRealAnalysis,
233*e5436536SAndroid Build Coastguard Worker pQmfImagAnalysis, 15 + (1));
234*e5436536SAndroid Build Coastguard Worker }
235*e5436536SAndroid Build Coastguard Worker if (ts == self->pQmfDomain->globalConf.nQmfTimeSlots - 1) {
236*e5436536SAndroid Build Coastguard Worker /* Is currently also needed in case we dont have any overlap. We need to
237*e5436536SAndroid Build Coastguard Worker * save lb_scale to ov_lb_scale */
238*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_SaveOverlap(&self->pQmfDomain->QmfDomainIn[ch], 0);
239*e5436536SAndroid Build Coastguard Worker }
240*e5436536SAndroid Build Coastguard Worker
241*e5436536SAndroid Build Coastguard Worker /* Apply clip protection to output. */
242*e5436536SAndroid Build Coastguard Worker if (!isTwoChMode(self->upmixType) && !bypassMode) {
243*e5436536SAndroid Build Coastguard Worker int i;
244*e5436536SAndroid Build Coastguard Worker for (i = 0; i < self->qmfBands; i++) {
245*e5436536SAndroid Build Coastguard Worker qmfReal__FDK[ch][i] =
246*e5436536SAndroid Build Coastguard Worker fMult(qmfReal__FDK[ch][i], self->clipProtectGain__FDK);
247*e5436536SAndroid Build Coastguard Worker qmfImag__FDK[ch][i] =
248*e5436536SAndroid Build Coastguard Worker fMult(qmfImag__FDK[ch][i], self->clipProtectGain__FDK);
249*e5436536SAndroid Build Coastguard Worker }
250*e5436536SAndroid Build Coastguard Worker }
251*e5436536SAndroid Build Coastguard Worker
252*e5436536SAndroid Build Coastguard Worker } /* End of loop over numInputChannels */
253*e5436536SAndroid Build Coastguard Worker }
254*e5436536SAndroid Build Coastguard Worker
255*e5436536SAndroid Build Coastguard Worker self->qmfInputDelayBufPos =
256*e5436536SAndroid Build Coastguard Worker (self->qmfInputDelayBufPos + 1) % self->pc_filterdelay;
257*e5436536SAndroid Build Coastguard Worker
258*e5436536SAndroid Build Coastguard Worker return err;
259*e5436536SAndroid Build Coastguard Worker }
260*e5436536SAndroid Build Coastguard Worker
261*e5436536SAndroid Build Coastguard Worker /*******************************************************************************
262*e5436536SAndroid Build Coastguard Worker Functionname: SpatialDecHybridAnalysis
263*e5436536SAndroid Build Coastguard Worker *******************************************************************************
264*e5436536SAndroid Build Coastguard Worker
265*e5436536SAndroid Build Coastguard Worker Description:
266*e5436536SAndroid Build Coastguard Worker
267*e5436536SAndroid Build Coastguard Worker Arguments:
268*e5436536SAndroid Build Coastguard Worker
269*e5436536SAndroid Build Coastguard Worker Input:
270*e5436536SAndroid Build Coastguard Worker float** pointers[4] leftReal, leftIm, rightReal, rightIm
271*e5436536SAndroid Build Coastguard Worker
272*e5436536SAndroid Build Coastguard Worker Output:
273*e5436536SAndroid Build Coastguard Worker float self->qmfInputReal[MAX_INPUT_CHANNELS][MAX_TIME_SLOTS][MAX_QMF_BANDS];
274*e5436536SAndroid Build Coastguard Worker float self->qmfInputImag[MAX_INPUT_CHANNELS][MAX_TIME_SLOTS][MAX_QMF_BANDS];
275*e5436536SAndroid Build Coastguard Worker
276*e5436536SAndroid Build Coastguard Worker float
277*e5436536SAndroid Build Coastguard Worker self->hybInputReal[MAX_INPUT_CHANNELS][MAX_TIME_SLOTS][MAX_HYBRID_BANDS]; float
278*e5436536SAndroid Build Coastguard Worker self->hybInputImag[MAX_INPUT_CHANNELS][MAX_TIME_SLOTS][MAX_HYBRID_BANDS];
279*e5436536SAndroid Build Coastguard Worker
280*e5436536SAndroid Build Coastguard Worker
281*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
SpatialDecHybridAnalysis(spatialDec * self,FIXP_DBL ** qmfInputReal,FIXP_DBL ** qmfInputImag,FIXP_DBL ** hybOutputReal,FIXP_DBL ** hybOutputImag,const INT ts,const INT numInputChannels)282*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecHybridAnalysis(spatialDec *self, FIXP_DBL **qmfInputReal,
283*e5436536SAndroid Build Coastguard Worker FIXP_DBL **qmfInputImag,
284*e5436536SAndroid Build Coastguard Worker FIXP_DBL **hybOutputReal,
285*e5436536SAndroid Build Coastguard Worker FIXP_DBL **hybOutputImag, const INT ts,
286*e5436536SAndroid Build Coastguard Worker const INT numInputChannels) {
287*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR err = MPS_OK;
288*e5436536SAndroid Build Coastguard Worker int ch;
289*e5436536SAndroid Build Coastguard Worker
290*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < numInputChannels;
291*e5436536SAndroid Build Coastguard Worker ch++) /* hybrid filtering for down-mix signals */
292*e5436536SAndroid Build Coastguard Worker {
293*e5436536SAndroid Build Coastguard Worker if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) {
294*e5436536SAndroid Build Coastguard Worker int k;
295*e5436536SAndroid Build Coastguard Worker /* No hybrid filtering. Just copy the QMF data. */
296*e5436536SAndroid Build Coastguard Worker for (k = 0; k < self->hybridBands; k += 1) {
297*e5436536SAndroid Build Coastguard Worker hybOutputReal[ch][k] = qmfInputReal[ch][k];
298*e5436536SAndroid Build Coastguard Worker hybOutputImag[ch][k] = qmfInputImag[ch][k];
299*e5436536SAndroid Build Coastguard Worker }
300*e5436536SAndroid Build Coastguard Worker } else {
301*e5436536SAndroid Build Coastguard Worker self->hybridAnalysis[ch].hfMode = self->bShareDelayWithSBR;
302*e5436536SAndroid Build Coastguard Worker
303*e5436536SAndroid Build Coastguard Worker if (self->stereoConfigIndex == 3)
304*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(self->hybridAnalysis[ch].hfMode == 0);
305*e5436536SAndroid Build Coastguard Worker FDKhybridAnalysisApply(&self->hybridAnalysis[ch], qmfInputReal[ch],
306*e5436536SAndroid Build Coastguard Worker qmfInputImag[ch], hybOutputReal[ch],
307*e5436536SAndroid Build Coastguard Worker hybOutputImag[ch]);
308*e5436536SAndroid Build Coastguard Worker }
309*e5436536SAndroid Build Coastguard Worker }
310*e5436536SAndroid Build Coastguard Worker
311*e5436536SAndroid Build Coastguard Worker if ((self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_USAC) &&
312*e5436536SAndroid Build Coastguard Worker self->residualCoding) {
313*e5436536SAndroid Build Coastguard Worker self->hybridAnalysis[numInputChannels].hfMode = 0;
314*e5436536SAndroid Build Coastguard Worker FDKhybridAnalysisApply(
315*e5436536SAndroid Build Coastguard Worker &self->hybridAnalysis[numInputChannels],
316*e5436536SAndroid Build Coastguard Worker self->qmfResidualReal__FDK[0][0], self->qmfResidualImag__FDK[0][0],
317*e5436536SAndroid Build Coastguard Worker self->hybResidualReal__FDK[0], self->hybResidualImag__FDK[0]);
318*e5436536SAndroid Build Coastguard Worker }
319*e5436536SAndroid Build Coastguard Worker
320*e5436536SAndroid Build Coastguard Worker return err;
321*e5436536SAndroid Build Coastguard Worker }
322*e5436536SAndroid Build Coastguard Worker
SpatialDecCreateX(spatialDec * self,FIXP_DBL ** hybInputReal,FIXP_DBL ** hybInputImag,FIXP_DBL ** pxReal,FIXP_DBL ** pxImag)323*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecCreateX(spatialDec *self, FIXP_DBL **hybInputReal,
324*e5436536SAndroid Build Coastguard Worker FIXP_DBL **hybInputImag, FIXP_DBL **pxReal,
325*e5436536SAndroid Build Coastguard Worker FIXP_DBL **pxImag) {
326*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR err = MPS_OK;
327*e5436536SAndroid Build Coastguard Worker int row;
328*e5436536SAndroid Build Coastguard Worker
329*e5436536SAndroid Build Coastguard Worker /* Creating wDry */
330*e5436536SAndroid Build Coastguard Worker for (row = 0; row < self->numInputChannels; row++) {
331*e5436536SAndroid Build Coastguard Worker /* pointer to direct signals */
332*e5436536SAndroid Build Coastguard Worker pxReal[row] = hybInputReal[row];
333*e5436536SAndroid Build Coastguard Worker pxImag[row] = hybInputImag[row];
334*e5436536SAndroid Build Coastguard Worker }
335*e5436536SAndroid Build Coastguard Worker
336*e5436536SAndroid Build Coastguard Worker return err;
337*e5436536SAndroid Build Coastguard Worker }
338*e5436536SAndroid Build Coastguard Worker
M2ParamToKernelMult(FIXP_SGL * RESTRICT pKernel,FIXP_DBL * RESTRICT Mparam,FIXP_DBL * RESTRICT MparamPrev,int * RESTRICT pWidth,FIXP_SGL alpha__FDK,int nBands)339*e5436536SAndroid Build Coastguard Worker static void M2ParamToKernelMult(FIXP_SGL *RESTRICT pKernel,
340*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT Mparam,
341*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT MparamPrev,
342*e5436536SAndroid Build Coastguard Worker int *RESTRICT pWidth, FIXP_SGL alpha__FDK,
343*e5436536SAndroid Build Coastguard Worker int nBands) {
344*e5436536SAndroid Build Coastguard Worker int pb;
345*e5436536SAndroid Build Coastguard Worker
346*e5436536SAndroid Build Coastguard Worker for (pb = 0; pb < nBands; pb++) {
347*e5436536SAndroid Build Coastguard Worker FIXP_SGL tmp = FX_DBL2FX_SGL(
348*e5436536SAndroid Build Coastguard Worker interpolateParameter(alpha__FDK, Mparam[pb], MparamPrev[pb]));
349*e5436536SAndroid Build Coastguard Worker
350*e5436536SAndroid Build Coastguard Worker int i = pWidth[pb];
351*e5436536SAndroid Build Coastguard Worker if (i & 1) *pKernel++ = tmp;
352*e5436536SAndroid Build Coastguard Worker if (i & 2) {
353*e5436536SAndroid Build Coastguard Worker *pKernel++ = tmp;
354*e5436536SAndroid Build Coastguard Worker *pKernel++ = tmp;
355*e5436536SAndroid Build Coastguard Worker }
356*e5436536SAndroid Build Coastguard Worker for (i >>= 2; i--;) {
357*e5436536SAndroid Build Coastguard Worker *pKernel++ = tmp;
358*e5436536SAndroid Build Coastguard Worker *pKernel++ = tmp;
359*e5436536SAndroid Build Coastguard Worker *pKernel++ = tmp;
360*e5436536SAndroid Build Coastguard Worker *pKernel++ = tmp;
361*e5436536SAndroid Build Coastguard Worker }
362*e5436536SAndroid Build Coastguard Worker }
363*e5436536SAndroid Build Coastguard Worker }
364*e5436536SAndroid Build Coastguard Worker
SpatialDecApplyM1_CreateW_Mode212(spatialDec * self,const SPATIAL_BS_FRAME * frame,FIXP_DBL ** xReal,FIXP_DBL ** xImag,FIXP_DBL ** vReal,FIXP_DBL ** vImag)365*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecApplyM1_CreateW_Mode212(
366*e5436536SAndroid Build Coastguard Worker spatialDec *self, const SPATIAL_BS_FRAME *frame, FIXP_DBL **xReal,
367*e5436536SAndroid Build Coastguard Worker FIXP_DBL **xImag, FIXP_DBL **vReal, FIXP_DBL **vImag) {
368*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR err = MPS_OK;
369*e5436536SAndroid Build Coastguard Worker int res;
370*e5436536SAndroid Build Coastguard Worker FIXP_DBL *decorrInReal = vReal[0];
371*e5436536SAndroid Build Coastguard Worker FIXP_DBL *decorrInImag = vImag[0];
372*e5436536SAndroid Build Coastguard Worker
373*e5436536SAndroid Build Coastguard Worker /* M1 does not do anything in 212 mode, so use simplified processing */
374*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(self->numVChannels == 2);
375*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(self->numDirektSignals == 1);
376*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(self->numDecorSignals == 1);
377*e5436536SAndroid Build Coastguard Worker FDKmemcpy(vReal[0], xReal[0], self->hybridBands * sizeof(FIXP_DBL));
378*e5436536SAndroid Build Coastguard Worker FDKmemcpy(vImag[0], xImag[0], self->hybridBands * sizeof(FIXP_DBL));
379*e5436536SAndroid Build Coastguard Worker
380*e5436536SAndroid Build Coastguard Worker if (isTsdActive(frame->TsdData)) {
381*e5436536SAndroid Build Coastguard Worker /* Generate v_{x,nonTr} as input for allpass based decorrelator */
382*e5436536SAndroid Build Coastguard Worker TsdGenerateNonTr(self->hybridBands, frame->TsdData, self->TsdTs, vReal[0],
383*e5436536SAndroid Build Coastguard Worker vImag[0], vReal[1], vImag[1], &decorrInReal,
384*e5436536SAndroid Build Coastguard Worker &decorrInImag);
385*e5436536SAndroid Build Coastguard Worker }
386*e5436536SAndroid Build Coastguard Worker /* - Decorrelate */
387*e5436536SAndroid Build Coastguard Worker res = SpatialDecGetResidualIndex(self, 1);
388*e5436536SAndroid Build Coastguard Worker if (FDKdecorrelateApply(&self->apDecor[0], decorrInReal, decorrInImag,
389*e5436536SAndroid Build Coastguard Worker vReal[1], vImag[1],
390*e5436536SAndroid Build Coastguard Worker self->param2hyb[self->residualBands[res]])) {
391*e5436536SAndroid Build Coastguard Worker return MPS_NOTOK;
392*e5436536SAndroid Build Coastguard Worker }
393*e5436536SAndroid Build Coastguard Worker if (isTsdActive(frame->TsdData)) {
394*e5436536SAndroid Build Coastguard Worker /* Generate v_{x,Tr}, apply transient decorrelator and add to allpass based
395*e5436536SAndroid Build Coastguard Worker * decorrelator output */
396*e5436536SAndroid Build Coastguard Worker TsdApply(self->hybridBands, frame->TsdData, &self->TsdTs,
397*e5436536SAndroid Build Coastguard Worker vReal[0], /* input: v_x */
398*e5436536SAndroid Build Coastguard Worker vImag[0],
399*e5436536SAndroid Build Coastguard Worker vReal[1], /* input: d_{x,nonTr}; output: d_{x,nonTr} + d_{x,Tr} */
400*e5436536SAndroid Build Coastguard Worker vImag[1]);
401*e5436536SAndroid Build Coastguard Worker }
402*e5436536SAndroid Build Coastguard Worker
403*e5436536SAndroid Build Coastguard Worker /* Write residual signal in approriate parameter bands */
404*e5436536SAndroid Build Coastguard Worker if (self->residualBands[res] > 0) {
405*e5436536SAndroid Build Coastguard Worker int stopBand = self->param2hyb[self->residualBands[res]];
406*e5436536SAndroid Build Coastguard Worker FDKmemcpy(vReal[1], self->hybResidualReal__FDK[res],
407*e5436536SAndroid Build Coastguard Worker fixMin(stopBand, self->hybridBands) * sizeof(FIXP_DBL));
408*e5436536SAndroid Build Coastguard Worker FDKmemcpy(vImag[1], self->hybResidualImag__FDK[res],
409*e5436536SAndroid Build Coastguard Worker fixMin(stopBand, self->hybridBands) * sizeof(FIXP_DBL));
410*e5436536SAndroid Build Coastguard Worker } /* (self->residualBands[res]>0) */
411*e5436536SAndroid Build Coastguard Worker
412*e5436536SAndroid Build Coastguard Worker return err;
413*e5436536SAndroid Build Coastguard Worker }
414*e5436536SAndroid Build Coastguard Worker
SpatialDecApplyM2_Mode212(spatialDec * self,INT ps,const FIXP_SGL alpha,FIXP_DBL ** wReal,FIXP_DBL ** wImag,FIXP_DBL ** hybOutputRealDry,FIXP_DBL ** hybOutputImagDry)415*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecApplyM2_Mode212(spatialDec *self, INT ps,
416*e5436536SAndroid Build Coastguard Worker const FIXP_SGL alpha, FIXP_DBL **wReal,
417*e5436536SAndroid Build Coastguard Worker FIXP_DBL **wImag,
418*e5436536SAndroid Build Coastguard Worker FIXP_DBL **hybOutputRealDry,
419*e5436536SAndroid Build Coastguard Worker FIXP_DBL **hybOutputImagDry) {
420*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR err = MPS_OK;
421*e5436536SAndroid Build Coastguard Worker INT row;
422*e5436536SAndroid Build Coastguard Worker
423*e5436536SAndroid Build Coastguard Worker INT *pWidth = self->kernels_width;
424*e5436536SAndroid Build Coastguard Worker /* for stereoConfigIndex == 3 case hybridBands is < 71 */
425*e5436536SAndroid Build Coastguard Worker INT pb_max = self->kernels[self->hybridBands - 1] + 1;
426*e5436536SAndroid Build Coastguard Worker INT max_row = self->numOutputChannels;
427*e5436536SAndroid Build Coastguard Worker
428*e5436536SAndroid Build Coastguard Worker INT M2_exp = 0;
429*e5436536SAndroid Build Coastguard Worker if (self->residualCoding) M2_exp = 3;
430*e5436536SAndroid Build Coastguard Worker
431*e5436536SAndroid Build Coastguard Worker for (row = 0; row < max_row; row++) // 2 times
432*e5436536SAndroid Build Coastguard Worker {
433*e5436536SAndroid Build Coastguard Worker FIXP_DBL *Mparam0 = self->M2Real__FDK[row][0];
434*e5436536SAndroid Build Coastguard Worker FIXP_DBL *Mparam1 = self->M2Real__FDK[row][1];
435*e5436536SAndroid Build Coastguard Worker FIXP_DBL *MparamPrev0 = self->M2RealPrev__FDK[row][0];
436*e5436536SAndroid Build Coastguard Worker FIXP_DBL *MparamPrev1 = self->M2RealPrev__FDK[row][1];
437*e5436536SAndroid Build Coastguard Worker
438*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pHybOutRealDry = hybOutputRealDry[row];
439*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pHybOutImagDry = hybOutputImagDry[row];
440*e5436536SAndroid Build Coastguard Worker
441*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pWReal0 = wReal[0];
442*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pWReal1 = wReal[1];
443*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pWImag0 = wImag[0];
444*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pWImag1 = wImag[1];
445*e5436536SAndroid Build Coastguard Worker for (INT pb = 0; pb < pb_max; pb++) {
446*e5436536SAndroid Build Coastguard Worker FIXP_DBL tmp0, tmp1;
447*e5436536SAndroid Build Coastguard Worker
448*e5436536SAndroid Build Coastguard Worker tmp0 = interpolateParameter(alpha, Mparam0[pb], MparamPrev0[pb]);
449*e5436536SAndroid Build Coastguard Worker tmp1 = interpolateParameter(alpha, Mparam1[pb], MparamPrev1[pb]);
450*e5436536SAndroid Build Coastguard Worker
451*e5436536SAndroid Build Coastguard Worker INT i = pWidth[pb];
452*e5436536SAndroid Build Coastguard Worker
453*e5436536SAndroid Build Coastguard Worker do // about 3-4 times
454*e5436536SAndroid Build Coastguard Worker {
455*e5436536SAndroid Build Coastguard Worker FIXP_DBL var0, var1, real, imag;
456*e5436536SAndroid Build Coastguard Worker
457*e5436536SAndroid Build Coastguard Worker var0 = *pWReal0++;
458*e5436536SAndroid Build Coastguard Worker var1 = *pWReal1++;
459*e5436536SAndroid Build Coastguard Worker real = fMultDiv2(var0, tmp0);
460*e5436536SAndroid Build Coastguard Worker var0 = *pWImag0++;
461*e5436536SAndroid Build Coastguard Worker real = fMultAddDiv2(real, var1, tmp1);
462*e5436536SAndroid Build Coastguard Worker var1 = *pWImag1++;
463*e5436536SAndroid Build Coastguard Worker imag = fMultDiv2(var0, tmp0);
464*e5436536SAndroid Build Coastguard Worker *pHybOutRealDry++ = real << (1 + M2_exp);
465*e5436536SAndroid Build Coastguard Worker imag = fMultAddDiv2(imag, var1, tmp1);
466*e5436536SAndroid Build Coastguard Worker *pHybOutImagDry++ = imag << (1 + M2_exp);
467*e5436536SAndroid Build Coastguard Worker } while (--i != 0);
468*e5436536SAndroid Build Coastguard Worker }
469*e5436536SAndroid Build Coastguard Worker }
470*e5436536SAndroid Build Coastguard Worker return err;
471*e5436536SAndroid Build Coastguard Worker }
472*e5436536SAndroid Build Coastguard Worker
SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(spatialDec * self,INT ps,const FIXP_SGL alpha,FIXP_DBL ** wReal,FIXP_DBL ** wImag,FIXP_DBL ** hybOutputRealDry,FIXP_DBL ** hybOutputImagDry)473*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding(
474*e5436536SAndroid Build Coastguard Worker spatialDec *self, INT ps, const FIXP_SGL alpha, FIXP_DBL **wReal,
475*e5436536SAndroid Build Coastguard Worker FIXP_DBL **wImag, FIXP_DBL **hybOutputRealDry,
476*e5436536SAndroid Build Coastguard Worker FIXP_DBL **hybOutputImagDry) {
477*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR err = MPS_OK;
478*e5436536SAndroid Build Coastguard Worker INT row;
479*e5436536SAndroid Build Coastguard Worker INT scale_param_m2;
480*e5436536SAndroid Build Coastguard Worker INT *pWidth = self->kernels_width;
481*e5436536SAndroid Build Coastguard Worker INT pb_max = self->kernels[self->hybridBands - 1] + 1;
482*e5436536SAndroid Build Coastguard Worker
483*e5436536SAndroid Build Coastguard Worker scale_param_m2 = SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2;
484*e5436536SAndroid Build Coastguard Worker
485*e5436536SAndroid Build Coastguard Worker for (row = 0; row < self->numM2rows; row++) {
486*e5436536SAndroid Build Coastguard Worker INT qs, pb;
487*e5436536SAndroid Build Coastguard Worker
488*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pWReal0 = wReal[0];
489*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pWImag0 = wImag[0];
490*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pWReal1 = wReal[1];
491*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pWImag1 = wImag[1];
492*e5436536SAndroid Build Coastguard Worker
493*e5436536SAndroid Build Coastguard Worker FIXP_DBL *MReal0 = self->M2Real__FDK[row][0];
494*e5436536SAndroid Build Coastguard Worker FIXP_DBL *MImag0 = self->M2Imag__FDK[row][0];
495*e5436536SAndroid Build Coastguard Worker FIXP_DBL *MReal1 = self->M2Real__FDK[row][1];
496*e5436536SAndroid Build Coastguard Worker FIXP_DBL *MRealPrev0 = self->M2RealPrev__FDK[row][0];
497*e5436536SAndroid Build Coastguard Worker FIXP_DBL *MImagPrev0 = self->M2ImagPrev__FDK[row][0];
498*e5436536SAndroid Build Coastguard Worker FIXP_DBL *MRealPrev1 = self->M2RealPrev__FDK[row][1];
499*e5436536SAndroid Build Coastguard Worker
500*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pHybOutRealDry = hybOutputRealDry[row];
501*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pHybOutImagDry = hybOutputImagDry[row];
502*e5436536SAndroid Build Coastguard Worker
503*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(!(self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD));
504*e5436536SAndroid Build Coastguard Worker FDK_ASSERT((pWidth[0] + pWidth[1]) >= 3);
505*e5436536SAndroid Build Coastguard Worker
506*e5436536SAndroid Build Coastguard Worker for (pb = 0, qs = 3; pb < 2; pb++) {
507*e5436536SAndroid Build Coastguard Worker INT s;
508*e5436536SAndroid Build Coastguard Worker FIXP_DBL maxVal;
509*e5436536SAndroid Build Coastguard Worker FIXP_DBL mReal1;
510*e5436536SAndroid Build Coastguard Worker FIXP_DBL mReal0, mImag0;
511*e5436536SAndroid Build Coastguard Worker FIXP_DBL iReal0, iImag0, iReal1;
512*e5436536SAndroid Build Coastguard Worker
513*e5436536SAndroid Build Coastguard Worker iReal0 = interpolateParameter(alpha, MReal0[pb], MRealPrev0[pb]);
514*e5436536SAndroid Build Coastguard Worker iImag0 = -interpolateParameter(alpha, MImag0[pb], MImagPrev0[pb]);
515*e5436536SAndroid Build Coastguard Worker iReal1 = interpolateParameter(alpha, MReal1[pb], MRealPrev1[pb]);
516*e5436536SAndroid Build Coastguard Worker
517*e5436536SAndroid Build Coastguard Worker maxVal = fAbs(iReal0) | fAbs(iImag0);
518*e5436536SAndroid Build Coastguard Worker maxVal |= fAbs(iReal1);
519*e5436536SAndroid Build Coastguard Worker
520*e5436536SAndroid Build Coastguard Worker s = fMin(CntLeadingZeros(maxVal) - 2, scale_param_m2);
521*e5436536SAndroid Build Coastguard Worker
522*e5436536SAndroid Build Coastguard Worker mReal0 = scaleValue(iReal0, s);
523*e5436536SAndroid Build Coastguard Worker mImag0 = scaleValue(iImag0, s);
524*e5436536SAndroid Build Coastguard Worker mReal1 = scaleValue(iReal1, s);
525*e5436536SAndroid Build Coastguard Worker
526*e5436536SAndroid Build Coastguard Worker s = scale_param_m2 - s;
527*e5436536SAndroid Build Coastguard Worker
528*e5436536SAndroid Build Coastguard Worker INT i = pWidth[pb];
529*e5436536SAndroid Build Coastguard Worker
530*e5436536SAndroid Build Coastguard Worker do {
531*e5436536SAndroid Build Coastguard Worker FIXP_DBL real, imag, wReal0, wImag0, wReal1, wImag1;
532*e5436536SAndroid Build Coastguard Worker
533*e5436536SAndroid Build Coastguard Worker wReal0 = *pWReal0++;
534*e5436536SAndroid Build Coastguard Worker wImag0 = *pWImag0++;
535*e5436536SAndroid Build Coastguard Worker wReal1 = *pWReal1++;
536*e5436536SAndroid Build Coastguard Worker wImag1 = *pWImag1++;
537*e5436536SAndroid Build Coastguard Worker
538*e5436536SAndroid Build Coastguard Worker cplxMultDiv2(&real, &imag, wReal0, wImag0, mReal0, mImag0);
539*e5436536SAndroid Build Coastguard Worker
540*e5436536SAndroid Build Coastguard Worker *pHybOutRealDry++ = fMultAddDiv2(real, wReal1, mReal1) << s;
541*e5436536SAndroid Build Coastguard Worker *pHybOutImagDry++ = fMultAddDiv2(imag, wImag1, mReal1) << s;
542*e5436536SAndroid Build Coastguard Worker
543*e5436536SAndroid Build Coastguard Worker if (qs > 0) {
544*e5436536SAndroid Build Coastguard Worker mImag0 = -mImag0;
545*e5436536SAndroid Build Coastguard Worker qs--;
546*e5436536SAndroid Build Coastguard Worker }
547*e5436536SAndroid Build Coastguard Worker } while (--i != 0);
548*e5436536SAndroid Build Coastguard Worker }
549*e5436536SAndroid Build Coastguard Worker
550*e5436536SAndroid Build Coastguard Worker for (; pb < pb_max; pb++) {
551*e5436536SAndroid Build Coastguard Worker INT s;
552*e5436536SAndroid Build Coastguard Worker FIXP_DBL maxVal;
553*e5436536SAndroid Build Coastguard Worker FIXP_SGL mReal1;
554*e5436536SAndroid Build Coastguard Worker FIXP_SGL mReal0, mImag0;
555*e5436536SAndroid Build Coastguard Worker FIXP_DBL iReal0, iImag0, iReal1;
556*e5436536SAndroid Build Coastguard Worker
557*e5436536SAndroid Build Coastguard Worker iReal0 = interpolateParameter(alpha, MReal0[pb], MRealPrev0[pb]);
558*e5436536SAndroid Build Coastguard Worker iImag0 = interpolateParameter(alpha, MImag0[pb], MImagPrev0[pb]);
559*e5436536SAndroid Build Coastguard Worker iReal1 = interpolateParameter(alpha, MReal1[pb], MRealPrev1[pb]);
560*e5436536SAndroid Build Coastguard Worker
561*e5436536SAndroid Build Coastguard Worker maxVal = fAbs(iReal0) | fAbs(iImag0);
562*e5436536SAndroid Build Coastguard Worker maxVal |= fAbs(iReal1);
563*e5436536SAndroid Build Coastguard Worker
564*e5436536SAndroid Build Coastguard Worker s = fMin(CntLeadingZeros(maxVal) - 2, scale_param_m2);
565*e5436536SAndroid Build Coastguard Worker
566*e5436536SAndroid Build Coastguard Worker mReal0 = FX_DBL2FX_SGL(scaleValue(iReal0, s));
567*e5436536SAndroid Build Coastguard Worker mImag0 = FX_DBL2FX_SGL(scaleValue(iImag0, s));
568*e5436536SAndroid Build Coastguard Worker mReal1 = FX_DBL2FX_SGL(scaleValue(iReal1, s));
569*e5436536SAndroid Build Coastguard Worker
570*e5436536SAndroid Build Coastguard Worker s = scale_param_m2 - s;
571*e5436536SAndroid Build Coastguard Worker
572*e5436536SAndroid Build Coastguard Worker INT i = pWidth[pb];
573*e5436536SAndroid Build Coastguard Worker
574*e5436536SAndroid Build Coastguard Worker do {
575*e5436536SAndroid Build Coastguard Worker FIXP_DBL real, imag, wReal0, wImag0, wReal1, wImag1;
576*e5436536SAndroid Build Coastguard Worker
577*e5436536SAndroid Build Coastguard Worker wReal0 = *pWReal0++;
578*e5436536SAndroid Build Coastguard Worker wImag0 = *pWImag0++;
579*e5436536SAndroid Build Coastguard Worker wReal1 = *pWReal1++;
580*e5436536SAndroid Build Coastguard Worker wImag1 = *pWImag1++;
581*e5436536SAndroid Build Coastguard Worker
582*e5436536SAndroid Build Coastguard Worker cplxMultDiv2(&real, &imag, wReal0, wImag0, mReal0, mImag0);
583*e5436536SAndroid Build Coastguard Worker
584*e5436536SAndroid Build Coastguard Worker *pHybOutRealDry++ = fMultAddDiv2(real, wReal1, mReal1) << s;
585*e5436536SAndroid Build Coastguard Worker *pHybOutImagDry++ = fMultAddDiv2(imag, wImag1, mReal1) << s;
586*e5436536SAndroid Build Coastguard Worker } while (--i != 0);
587*e5436536SAndroid Build Coastguard Worker }
588*e5436536SAndroid Build Coastguard Worker }
589*e5436536SAndroid Build Coastguard Worker
590*e5436536SAndroid Build Coastguard Worker return err;
591*e5436536SAndroid Build Coastguard Worker }
592*e5436536SAndroid Build Coastguard Worker
SpatialDecApplyM2(spatialDec * self,INT ps,const FIXP_SGL alpha,FIXP_DBL ** wReal,FIXP_DBL ** wImag,FIXP_DBL ** hybOutputRealDry,FIXP_DBL ** hybOutputImagDry,FIXP_DBL ** hybOutputRealWet,FIXP_DBL ** hybOutputImagWet)593*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha,
594*e5436536SAndroid Build Coastguard Worker FIXP_DBL **wReal, FIXP_DBL **wImag,
595*e5436536SAndroid Build Coastguard Worker FIXP_DBL **hybOutputRealDry,
596*e5436536SAndroid Build Coastguard Worker FIXP_DBL **hybOutputImagDry,
597*e5436536SAndroid Build Coastguard Worker FIXP_DBL **hybOutputRealWet,
598*e5436536SAndroid Build Coastguard Worker FIXP_DBL **hybOutputImagWet) {
599*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR err = MPS_OK;
600*e5436536SAndroid Build Coastguard Worker
601*e5436536SAndroid Build Coastguard Worker {
602*e5436536SAndroid Build Coastguard Worker int qs, row, col;
603*e5436536SAndroid Build Coastguard Worker int complexHybBands;
604*e5436536SAndroid Build Coastguard Worker int complexParBands;
605*e5436536SAndroid Build Coastguard Worker int scale_param_m2 = 0;
606*e5436536SAndroid Build Coastguard Worker int toolsDisabled;
607*e5436536SAndroid Build Coastguard Worker
608*e5436536SAndroid Build Coastguard Worker UCHAR activParamBands;
609*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pWReal, *RESTRICT pWImag, *RESTRICT pHybOutRealDry,
610*e5436536SAndroid Build Coastguard Worker *RESTRICT pHybOutImagDry, *RESTRICT pHybOutRealWet,
611*e5436536SAndroid Build Coastguard Worker *RESTRICT pHybOutImagWet;
612*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_START(pKernel, FIXP_SGL, MAX_HYBRID_BANDS);
613*e5436536SAndroid Build Coastguard Worker
614*e5436536SAndroid Build Coastguard Worker /* The wet signal is added to the dry signal directly in applyM2 if GES and
615*e5436536SAndroid Build Coastguard Worker * STP are disabled */
616*e5436536SAndroid Build Coastguard Worker toolsDisabled =
617*e5436536SAndroid Build Coastguard Worker ((self->tempShapeConfig == 1) || (self->tempShapeConfig == 2)) ? 0 : 1;
618*e5436536SAndroid Build Coastguard Worker
619*e5436536SAndroid Build Coastguard Worker {
620*e5436536SAndroid Build Coastguard Worker complexHybBands = self->hybridBands;
621*e5436536SAndroid Build Coastguard Worker complexParBands = self->numParameterBands;
622*e5436536SAndroid Build Coastguard Worker }
623*e5436536SAndroid Build Coastguard Worker
624*e5436536SAndroid Build Coastguard Worker FDKmemclear(hybOutputImagDry[0],
625*e5436536SAndroid Build Coastguard Worker self->createParams.maxNumOutputChannels *
626*e5436536SAndroid Build Coastguard Worker self->createParams.maxNumCmplxHybBands * sizeof(FIXP_DBL));
627*e5436536SAndroid Build Coastguard Worker FDKmemclear(hybOutputRealDry[0], self->createParams.maxNumOutputChannels *
628*e5436536SAndroid Build Coastguard Worker self->createParams.maxNumHybridBands *
629*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL));
630*e5436536SAndroid Build Coastguard Worker
631*e5436536SAndroid Build Coastguard Worker if (!toolsDisabled) {
632*e5436536SAndroid Build Coastguard Worker FDKmemclear(hybOutputRealWet[0],
633*e5436536SAndroid Build Coastguard Worker self->createParams.maxNumOutputChannels *
634*e5436536SAndroid Build Coastguard Worker self->createParams.maxNumHybridBands * sizeof(FIXP_DBL));
635*e5436536SAndroid Build Coastguard Worker FDKmemclear(hybOutputImagWet[0],
636*e5436536SAndroid Build Coastguard Worker self->createParams.maxNumOutputChannels *
637*e5436536SAndroid Build Coastguard Worker self->createParams.maxNumCmplxHybBands *
638*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL));
639*e5436536SAndroid Build Coastguard Worker }
640*e5436536SAndroid Build Coastguard Worker
641*e5436536SAndroid Build Coastguard Worker if (self->phaseCoding == 3) {
642*e5436536SAndroid Build Coastguard Worker scale_param_m2 = -(SCALE_DATA_APPLY_M2_PC - 1);
643*e5436536SAndroid Build Coastguard Worker }
644*e5436536SAndroid Build Coastguard Worker
645*e5436536SAndroid Build Coastguard Worker for (row = 0; row < self->numM2rows; row++) {
646*e5436536SAndroid Build Coastguard Worker pHybOutRealDry = hybOutputRealDry[row];
647*e5436536SAndroid Build Coastguard Worker pHybOutImagDry = hybOutputImagDry[row];
648*e5436536SAndroid Build Coastguard Worker
649*e5436536SAndroid Build Coastguard Worker if (toolsDisabled) {
650*e5436536SAndroid Build Coastguard Worker pHybOutRealWet = hybOutputRealDry[row];
651*e5436536SAndroid Build Coastguard Worker pHybOutImagWet = hybOutputImagDry[row];
652*e5436536SAndroid Build Coastguard Worker } else {
653*e5436536SAndroid Build Coastguard Worker pHybOutRealWet = hybOutputRealWet[row];
654*e5436536SAndroid Build Coastguard Worker pHybOutImagWet = hybOutputImagWet[row];
655*e5436536SAndroid Build Coastguard Worker }
656*e5436536SAndroid Build Coastguard Worker
657*e5436536SAndroid Build Coastguard Worker for (col = 0; col < self->numDirektSignals; col++) {
658*e5436536SAndroid Build Coastguard Worker if (self->pActivM2ParamBands ==
659*e5436536SAndroid Build Coastguard Worker 0) { /* default setting, calculate all rows and columns */
660*e5436536SAndroid Build Coastguard Worker activParamBands = 1;
661*e5436536SAndroid Build Coastguard Worker } else {
662*e5436536SAndroid Build Coastguard Worker if (self->pActivM2ParamBands[MAX_M2_INPUT * row +
663*e5436536SAndroid Build Coastguard Worker col]) /* table with activ and inactiv
664*e5436536SAndroid Build Coastguard Worker bands exists for current
665*e5436536SAndroid Build Coastguard Worker configuration */
666*e5436536SAndroid Build Coastguard Worker activParamBands = 1;
667*e5436536SAndroid Build Coastguard Worker else
668*e5436536SAndroid Build Coastguard Worker activParamBands = 0;
669*e5436536SAndroid Build Coastguard Worker }
670*e5436536SAndroid Build Coastguard Worker if (activParamBands) {
671*e5436536SAndroid Build Coastguard Worker pWReal = wReal[col];
672*e5436536SAndroid Build Coastguard Worker pWImag = wImag[col];
673*e5436536SAndroid Build Coastguard Worker
674*e5436536SAndroid Build Coastguard Worker M2ParamToKernelMult(pKernel, self->M2Real__FDK[row][col],
675*e5436536SAndroid Build Coastguard Worker self->M2RealPrev__FDK[row][col],
676*e5436536SAndroid Build Coastguard Worker self->kernels_width, alpha,
677*e5436536SAndroid Build Coastguard Worker self->numParameterBands);
678*e5436536SAndroid Build Coastguard Worker
679*e5436536SAndroid Build Coastguard Worker if (1 && (self->phaseCoding != 3)) {
680*e5436536SAndroid Build Coastguard Worker /* direct signals */
681*e5436536SAndroid Build Coastguard Worker {
682*e5436536SAndroid Build Coastguard Worker /* only one sample will be assigned to each row, hence
683*e5436536SAndroid Build Coastguard Worker * accumulation is not neccessary; that is valid for all
684*e5436536SAndroid Build Coastguard Worker * configurations */
685*e5436536SAndroid Build Coastguard Worker for (qs = 0; qs < complexHybBands; qs++) {
686*e5436536SAndroid Build Coastguard Worker pHybOutRealDry[qs] = fMult(pWReal[qs], pKernel[qs]);
687*e5436536SAndroid Build Coastguard Worker pHybOutImagDry[qs] = fMult(pWImag[qs], pKernel[qs]);
688*e5436536SAndroid Build Coastguard Worker }
689*e5436536SAndroid Build Coastguard Worker }
690*e5436536SAndroid Build Coastguard Worker } else { /* isBinauralMode(self->upmixType) */
691*e5436536SAndroid Build Coastguard Worker
692*e5436536SAndroid Build Coastguard Worker for (qs = 0; qs < complexHybBands; qs++) {
693*e5436536SAndroid Build Coastguard Worker pHybOutRealDry[qs] += SAC_DEC_APPLY_M2_SCALE(
694*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
695*e5436536SAndroid Build Coastguard Worker pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
696*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
697*e5436536SAndroid Build Coastguard Worker }
698*e5436536SAndroid Build Coastguard Worker
699*e5436536SAndroid Build Coastguard Worker M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col],
700*e5436536SAndroid Build Coastguard Worker self->M2ImagPrev__FDK[row][col],
701*e5436536SAndroid Build Coastguard Worker self->kernels_width, alpha, complexParBands);
702*e5436536SAndroid Build Coastguard Worker
703*e5436536SAndroid Build Coastguard Worker /* direct signals sign is -1 for qs = 0,2 */
704*e5436536SAndroid Build Coastguard Worker pHybOutRealDry[0] += SAC_DEC_APPLY_M2_SCALE(
705*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
706*e5436536SAndroid Build Coastguard Worker pHybOutImagDry[0] -= SAC_DEC_APPLY_M2_SCALE(
707*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
708*e5436536SAndroid Build Coastguard Worker
709*e5436536SAndroid Build Coastguard Worker pHybOutRealDry[2] += SAC_DEC_APPLY_M2_SCALE(
710*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
711*e5436536SAndroid Build Coastguard Worker pHybOutImagDry[2] -= SAC_DEC_APPLY_M2_SCALE(
712*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
713*e5436536SAndroid Build Coastguard Worker
714*e5436536SAndroid Build Coastguard Worker /* direct signals sign is +1 for qs = 1,3,4,5,...,complexHybBands */
715*e5436536SAndroid Build Coastguard Worker pHybOutRealDry[1] -= SAC_DEC_APPLY_M2_SCALE(
716*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
717*e5436536SAndroid Build Coastguard Worker pHybOutImagDry[1] += SAC_DEC_APPLY_M2_SCALE(
718*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
719*e5436536SAndroid Build Coastguard Worker
720*e5436536SAndroid Build Coastguard Worker for (qs = 3; qs < complexHybBands; qs++) {
721*e5436536SAndroid Build Coastguard Worker pHybOutRealDry[qs] -= SAC_DEC_APPLY_M2_SCALE(
722*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
723*e5436536SAndroid Build Coastguard Worker pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
724*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
725*e5436536SAndroid Build Coastguard Worker }
726*e5436536SAndroid Build Coastguard Worker } /* self->upmixType */
727*e5436536SAndroid Build Coastguard Worker } /* if (activParamBands) */
728*e5436536SAndroid Build Coastguard Worker } /* self->numDirektSignals */
729*e5436536SAndroid Build Coastguard Worker
730*e5436536SAndroid Build Coastguard Worker for (; col < self->numVChannels; col++) {
731*e5436536SAndroid Build Coastguard Worker if (self->pActivM2ParamBands ==
732*e5436536SAndroid Build Coastguard Worker 0) { /* default setting, calculate all rows and columns */
733*e5436536SAndroid Build Coastguard Worker activParamBands = 1;
734*e5436536SAndroid Build Coastguard Worker } else {
735*e5436536SAndroid Build Coastguard Worker if (self->pActivM2ParamBands[MAX_M2_INPUT * row +
736*e5436536SAndroid Build Coastguard Worker col]) /* table with activ and inactiv
737*e5436536SAndroid Build Coastguard Worker bands exists for current
738*e5436536SAndroid Build Coastguard Worker configuration */
739*e5436536SAndroid Build Coastguard Worker activParamBands = 1;
740*e5436536SAndroid Build Coastguard Worker else
741*e5436536SAndroid Build Coastguard Worker activParamBands = 0;
742*e5436536SAndroid Build Coastguard Worker }
743*e5436536SAndroid Build Coastguard Worker
744*e5436536SAndroid Build Coastguard Worker if (activParamBands) {
745*e5436536SAndroid Build Coastguard Worker int resBandIndex;
746*e5436536SAndroid Build Coastguard Worker int resHybIndex;
747*e5436536SAndroid Build Coastguard Worker
748*e5436536SAndroid Build Coastguard Worker resBandIndex =
749*e5436536SAndroid Build Coastguard Worker self->residualBands[SpatialDecGetResidualIndex(self, col)];
750*e5436536SAndroid Build Coastguard Worker resHybIndex = self->param2hyb[resBandIndex];
751*e5436536SAndroid Build Coastguard Worker
752*e5436536SAndroid Build Coastguard Worker pWReal = wReal[col];
753*e5436536SAndroid Build Coastguard Worker pWImag = wImag[col];
754*e5436536SAndroid Build Coastguard Worker
755*e5436536SAndroid Build Coastguard Worker M2ParamToKernelMult(pKernel, self->M2Real__FDK[row][col],
756*e5436536SAndroid Build Coastguard Worker self->M2RealPrev__FDK[row][col],
757*e5436536SAndroid Build Coastguard Worker self->kernels_width, alpha,
758*e5436536SAndroid Build Coastguard Worker self->numParameterBands);
759*e5436536SAndroid Build Coastguard Worker
760*e5436536SAndroid Build Coastguard Worker if (1 && (self->phaseCoding != 3)) {
761*e5436536SAndroid Build Coastguard Worker /* residual signals */
762*e5436536SAndroid Build Coastguard Worker for (qs = 0; qs < resHybIndex; qs++) {
763*e5436536SAndroid Build Coastguard Worker pHybOutRealDry[qs] += fMult(pWReal[qs], pKernel[qs]);
764*e5436536SAndroid Build Coastguard Worker pHybOutImagDry[qs] += fMult(pWImag[qs], pKernel[qs]);
765*e5436536SAndroid Build Coastguard Worker }
766*e5436536SAndroid Build Coastguard Worker /* decor signals */
767*e5436536SAndroid Build Coastguard Worker for (; qs < complexHybBands; qs++) {
768*e5436536SAndroid Build Coastguard Worker pHybOutRealWet[qs] += fMult(pWReal[qs], pKernel[qs]);
769*e5436536SAndroid Build Coastguard Worker pHybOutImagWet[qs] += fMult(pWImag[qs], pKernel[qs]);
770*e5436536SAndroid Build Coastguard Worker }
771*e5436536SAndroid Build Coastguard Worker } else { /* self->upmixType */
772*e5436536SAndroid Build Coastguard Worker /* residual signals */
773*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pHybOutReal;
774*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pHybOutImag;
775*e5436536SAndroid Build Coastguard Worker
776*e5436536SAndroid Build Coastguard Worker for (qs = 0; qs < resHybIndex; qs++) {
777*e5436536SAndroid Build Coastguard Worker pHybOutRealDry[qs] += SAC_DEC_APPLY_M2_SCALE(
778*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
779*e5436536SAndroid Build Coastguard Worker pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
780*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
781*e5436536SAndroid Build Coastguard Worker }
782*e5436536SAndroid Build Coastguard Worker /* decor signals */
783*e5436536SAndroid Build Coastguard Worker for (; qs < complexHybBands; qs++) {
784*e5436536SAndroid Build Coastguard Worker pHybOutRealWet[qs] += SAC_DEC_APPLY_M2_SCALE(
785*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
786*e5436536SAndroid Build Coastguard Worker pHybOutImagWet[qs] += SAC_DEC_APPLY_M2_SCALE(
787*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
788*e5436536SAndroid Build Coastguard Worker }
789*e5436536SAndroid Build Coastguard Worker
790*e5436536SAndroid Build Coastguard Worker M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col],
791*e5436536SAndroid Build Coastguard Worker self->M2ImagPrev__FDK[row][col],
792*e5436536SAndroid Build Coastguard Worker self->kernels_width, alpha, complexParBands);
793*e5436536SAndroid Build Coastguard Worker
794*e5436536SAndroid Build Coastguard Worker /* direct signals sign is -1 for qs = 0,2 */
795*e5436536SAndroid Build Coastguard Worker /* direct signals sign is +1 for qs = 1,3.. */
796*e5436536SAndroid Build Coastguard Worker if (toolsDisabled) {
797*e5436536SAndroid Build Coastguard Worker pHybOutRealDry[0] += SAC_DEC_APPLY_M2_SCALE(
798*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
799*e5436536SAndroid Build Coastguard Worker pHybOutImagDry[0] -= SAC_DEC_APPLY_M2_SCALE(
800*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
801*e5436536SAndroid Build Coastguard Worker
802*e5436536SAndroid Build Coastguard Worker pHybOutRealDry[1] -= SAC_DEC_APPLY_M2_SCALE(
803*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
804*e5436536SAndroid Build Coastguard Worker pHybOutImagDry[1] += SAC_DEC_APPLY_M2_SCALE(
805*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
806*e5436536SAndroid Build Coastguard Worker
807*e5436536SAndroid Build Coastguard Worker pHybOutRealDry[2] += SAC_DEC_APPLY_M2_SCALE(
808*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
809*e5436536SAndroid Build Coastguard Worker pHybOutImagDry[2] -= SAC_DEC_APPLY_M2_SCALE(
810*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
811*e5436536SAndroid Build Coastguard Worker } else {
812*e5436536SAndroid Build Coastguard Worker pHybOutReal = &pHybOutRealDry[0];
813*e5436536SAndroid Build Coastguard Worker pHybOutImag = &pHybOutImagDry[0];
814*e5436536SAndroid Build Coastguard Worker if (0 == resHybIndex) {
815*e5436536SAndroid Build Coastguard Worker pHybOutReal = &pHybOutRealWet[0];
816*e5436536SAndroid Build Coastguard Worker pHybOutImag = &pHybOutImagWet[0];
817*e5436536SAndroid Build Coastguard Worker }
818*e5436536SAndroid Build Coastguard Worker pHybOutReal[0] += SAC_DEC_APPLY_M2_SCALE(
819*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2);
820*e5436536SAndroid Build Coastguard Worker pHybOutImag[0] -= SAC_DEC_APPLY_M2_SCALE(
821*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2);
822*e5436536SAndroid Build Coastguard Worker
823*e5436536SAndroid Build Coastguard Worker if (1 == resHybIndex) {
824*e5436536SAndroid Build Coastguard Worker pHybOutReal = &pHybOutRealWet[0];
825*e5436536SAndroid Build Coastguard Worker pHybOutImag = &pHybOutImagWet[0];
826*e5436536SAndroid Build Coastguard Worker }
827*e5436536SAndroid Build Coastguard Worker pHybOutReal[1] -= SAC_DEC_APPLY_M2_SCALE(
828*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2);
829*e5436536SAndroid Build Coastguard Worker pHybOutImag[1] += SAC_DEC_APPLY_M2_SCALE(
830*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2);
831*e5436536SAndroid Build Coastguard Worker
832*e5436536SAndroid Build Coastguard Worker if (2 == resHybIndex) {
833*e5436536SAndroid Build Coastguard Worker pHybOutReal = &pHybOutRealWet[0];
834*e5436536SAndroid Build Coastguard Worker pHybOutImag = &pHybOutImagWet[0];
835*e5436536SAndroid Build Coastguard Worker }
836*e5436536SAndroid Build Coastguard Worker pHybOutReal[2] += SAC_DEC_APPLY_M2_SCALE(
837*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2);
838*e5436536SAndroid Build Coastguard Worker pHybOutImag[2] -= SAC_DEC_APPLY_M2_SCALE(
839*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2);
840*e5436536SAndroid Build Coastguard Worker }
841*e5436536SAndroid Build Coastguard Worker
842*e5436536SAndroid Build Coastguard Worker for (qs = 3; qs < resHybIndex; qs++) {
843*e5436536SAndroid Build Coastguard Worker pHybOutRealDry[qs] -= SAC_DEC_APPLY_M2_SCALE(
844*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
845*e5436536SAndroid Build Coastguard Worker pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE(
846*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
847*e5436536SAndroid Build Coastguard Worker }
848*e5436536SAndroid Build Coastguard Worker /* decor signals */
849*e5436536SAndroid Build Coastguard Worker for (; qs < complexHybBands; qs++) {
850*e5436536SAndroid Build Coastguard Worker pHybOutRealWet[qs] -= SAC_DEC_APPLY_M2_SCALE(
851*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2);
852*e5436536SAndroid Build Coastguard Worker pHybOutImagWet[qs] += SAC_DEC_APPLY_M2_SCALE(
853*e5436536SAndroid Build Coastguard Worker fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2);
854*e5436536SAndroid Build Coastguard Worker }
855*e5436536SAndroid Build Coastguard Worker } /* self->upmixType */
856*e5436536SAndroid Build Coastguard Worker } /* if (activParamBands) { */
857*e5436536SAndroid Build Coastguard Worker } /* self->numVChannels */
858*e5436536SAndroid Build Coastguard Worker
859*e5436536SAndroid Build Coastguard Worker if (self->phaseCoding == 3) {
860*e5436536SAndroid Build Coastguard Worker scaleValuesSaturate(pHybOutRealDry, complexHybBands,
861*e5436536SAndroid Build Coastguard Worker SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
862*e5436536SAndroid Build Coastguard Worker scaleValuesSaturate(pHybOutImagDry, complexHybBands,
863*e5436536SAndroid Build Coastguard Worker SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
864*e5436536SAndroid Build Coastguard Worker
865*e5436536SAndroid Build Coastguard Worker if (!toolsDisabled) {
866*e5436536SAndroid Build Coastguard Worker scaleValuesSaturate(pHybOutRealWet, complexHybBands,
867*e5436536SAndroid Build Coastguard Worker SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
868*e5436536SAndroid Build Coastguard Worker scaleValuesSaturate(pHybOutImagWet, complexHybBands,
869*e5436536SAndroid Build Coastguard Worker SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC);
870*e5436536SAndroid Build Coastguard Worker }
871*e5436536SAndroid Build Coastguard Worker }
872*e5436536SAndroid Build Coastguard Worker }
873*e5436536SAndroid Build Coastguard Worker
874*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_END(pKernel, FIXP_SGL, MAX_HYBRID_BANDS);
875*e5436536SAndroid Build Coastguard Worker }
876*e5436536SAndroid Build Coastguard Worker
877*e5436536SAndroid Build Coastguard Worker return err;
878*e5436536SAndroid Build Coastguard Worker }
879*e5436536SAndroid Build Coastguard Worker
SpatialDecSynthesis(spatialDec * self,const INT ts,FIXP_DBL ** hybOutputReal,FIXP_DBL ** hybOutputImag,PCM_MPS * timeOut,const INT numInputChannels,const FDK_channelMapDescr * const mapDescr)880*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR SpatialDecSynthesis(spatialDec *self, const INT ts,
881*e5436536SAndroid Build Coastguard Worker FIXP_DBL **hybOutputReal,
882*e5436536SAndroid Build Coastguard Worker FIXP_DBL **hybOutputImag, PCM_MPS *timeOut,
883*e5436536SAndroid Build Coastguard Worker const INT numInputChannels,
884*e5436536SAndroid Build Coastguard Worker const FDK_channelMapDescr *const mapDescr) {
885*e5436536SAndroid Build Coastguard Worker SACDEC_ERROR err = MPS_OK;
886*e5436536SAndroid Build Coastguard Worker
887*e5436536SAndroid Build Coastguard Worker int ch;
888*e5436536SAndroid Build Coastguard Worker int stride, offset;
889*e5436536SAndroid Build Coastguard Worker
890*e5436536SAndroid Build Coastguard Worker stride = self->numOutputChannelsAT;
891*e5436536SAndroid Build Coastguard Worker offset = 1;
892*e5436536SAndroid Build Coastguard Worker
893*e5436536SAndroid Build Coastguard Worker PCM_MPS *pTimeOut__FDK =
894*e5436536SAndroid Build Coastguard Worker &timeOut[stride * self->pQmfDomain->globalConf.nBandsSynthesis * ts];
895*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_START(pQmfReal, FIXP_DBL, QMF_MAX_SYNTHESIS_BANDS);
896*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_START(pQmfImag, FIXP_DBL, QMF_MAX_SYNTHESIS_BANDS);
897*e5436536SAndroid Build Coastguard Worker
898*e5436536SAndroid Build Coastguard Worker for (ch = 0; ch < self->numOutputChannelsAT; ch++) {
899*e5436536SAndroid Build Coastguard Worker if (self->pConfigCurrent->syntaxFlags & SACDEC_SYNTAX_LD) {
900*e5436536SAndroid Build Coastguard Worker int k;
901*e5436536SAndroid Build Coastguard Worker /* No hybrid filtering. Just copy the QMF data. */
902*e5436536SAndroid Build Coastguard Worker for (k = 0; k < self->hybridBands; k += 1) {
903*e5436536SAndroid Build Coastguard Worker pQmfReal[k] = hybOutputReal[ch][k];
904*e5436536SAndroid Build Coastguard Worker pQmfImag[k] = hybOutputImag[ch][k];
905*e5436536SAndroid Build Coastguard Worker }
906*e5436536SAndroid Build Coastguard Worker } else {
907*e5436536SAndroid Build Coastguard Worker FDKhybridSynthesisApply(&self->hybridSynthesis[ch], hybOutputReal[ch],
908*e5436536SAndroid Build Coastguard Worker hybOutputImag[ch], pQmfReal, pQmfImag);
909*e5436536SAndroid Build Coastguard Worker }
910*e5436536SAndroid Build Coastguard Worker
911*e5436536SAndroid Build Coastguard Worker /* Map channel indices from MPEG Surround -> PCE style -> channelMapping[]
912*e5436536SAndroid Build Coastguard Worker */
913*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(self->numOutputChannelsAT <= 6);
914*e5436536SAndroid Build Coastguard Worker int outCh = FDK_chMapDescr_getMapValue(mapDescr, mapChannel(self, ch),
915*e5436536SAndroid Build Coastguard Worker self->numOutputChannelsAT);
916*e5436536SAndroid Build Coastguard Worker
917*e5436536SAndroid Build Coastguard Worker {
918*e5436536SAndroid Build Coastguard Worker if (self->stereoConfigIndex == 3) {
919*e5436536SAndroid Build Coastguard Worker /* MPS -> SBR */
920*e5436536SAndroid Build Coastguard Worker int i;
921*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pWorkBufReal, *pWorkBufImag;
922*e5436536SAndroid Build Coastguard Worker FDK_ASSERT((self->pQmfDomain->QmfDomainOut[outCh].fb.outGain_m ==
923*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)0x80000000) &&
924*e5436536SAndroid Build Coastguard Worker (self->pQmfDomain->QmfDomainOut[outCh].fb.outGain_e == 0));
925*e5436536SAndroid Build Coastguard Worker FDK_QmfDomain_GetWorkBuffer(&self->pQmfDomain->QmfDomainIn[outCh], ts,
926*e5436536SAndroid Build Coastguard Worker &pWorkBufReal, &pWorkBufImag);
927*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(self->qmfBands <=
928*e5436536SAndroid Build Coastguard Worker self->pQmfDomain->QmfDomainIn[outCh].workBuf_nBands);
929*e5436536SAndroid Build Coastguard Worker for (i = 0; i < self->qmfBands; i++) {
930*e5436536SAndroid Build Coastguard Worker pWorkBufReal[i] = pQmfReal[i];
931*e5436536SAndroid Build Coastguard Worker pWorkBufImag[i] = pQmfImag[i];
932*e5436536SAndroid Build Coastguard Worker }
933*e5436536SAndroid Build Coastguard Worker self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale =
934*e5436536SAndroid Build Coastguard Worker -7; /*-ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK;*/
935*e5436536SAndroid Build Coastguard Worker self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -=
936*e5436536SAndroid Build Coastguard Worker self->pQmfDomain->QmfDomainIn[outCh].fb.filterScale;
937*e5436536SAndroid Build Coastguard Worker self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -=
938*e5436536SAndroid Build Coastguard Worker self->clipProtectGainSF__FDK;
939*e5436536SAndroid Build Coastguard Worker
940*e5436536SAndroid Build Coastguard Worker self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -= (1);
941*e5436536SAndroid Build Coastguard Worker } else {
942*e5436536SAndroid Build Coastguard Worker /* Call the QMF synthesis for dry. */
943*e5436536SAndroid Build Coastguard Worker err = CalculateSpaceSynthesisQmf(&self->pQmfDomain->QmfDomainOut[outCh],
944*e5436536SAndroid Build Coastguard Worker pQmfReal, pQmfImag, stride,
945*e5436536SAndroid Build Coastguard Worker pTimeOut__FDK + (offset * outCh));
946*e5436536SAndroid Build Coastguard Worker }
947*e5436536SAndroid Build Coastguard Worker if (err != MPS_OK) goto bail;
948*e5436536SAndroid Build Coastguard Worker }
949*e5436536SAndroid Build Coastguard Worker } /* ch loop */
950*e5436536SAndroid Build Coastguard Worker
951*e5436536SAndroid Build Coastguard Worker bail:
952*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_END(pQmfImag, FIXP_DBL, QMF_MAX_SYNTHESIS_BANDS);
953*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_END(pQmfReal, FIXP_DBL, QMF_MAX_SYNTHESIS_BANDS);
954*e5436536SAndroid Build Coastguard Worker
955*e5436536SAndroid Build Coastguard Worker return err;
956*e5436536SAndroid Build Coastguard Worker }
957*e5436536SAndroid Build Coastguard Worker
SpatialDecBufferMatrices(spatialDec * self)958*e5436536SAndroid Build Coastguard Worker void SpatialDecBufferMatrices(spatialDec *self) {
959*e5436536SAndroid Build Coastguard Worker int row, col;
960*e5436536SAndroid Build Coastguard Worker int complexParBands;
961*e5436536SAndroid Build Coastguard Worker complexParBands = self->numParameterBands;
962*e5436536SAndroid Build Coastguard Worker
963*e5436536SAndroid Build Coastguard Worker /*
964*e5436536SAndroid Build Coastguard Worker buffer matrices M2
965*e5436536SAndroid Build Coastguard Worker */
966*e5436536SAndroid Build Coastguard Worker for (row = 0; row < self->numM2rows; row++) {
967*e5436536SAndroid Build Coastguard Worker for (col = 0; col < self->numVChannels; col++) {
968*e5436536SAndroid Build Coastguard Worker FDKmemcpy(self->M2RealPrev__FDK[row][col], self->M2Real__FDK[row][col],
969*e5436536SAndroid Build Coastguard Worker self->numParameterBands * sizeof(FIXP_DBL));
970*e5436536SAndroid Build Coastguard Worker if (0 || (self->phaseCoding == 3)) {
971*e5436536SAndroid Build Coastguard Worker FDKmemcpy(self->M2ImagPrev__FDK[row][col], self->M2Imag__FDK[row][col],
972*e5436536SAndroid Build Coastguard Worker complexParBands * sizeof(FIXP_DBL));
973*e5436536SAndroid Build Coastguard Worker }
974*e5436536SAndroid Build Coastguard Worker }
975*e5436536SAndroid Build Coastguard Worker }
976*e5436536SAndroid Build Coastguard Worker
977*e5436536SAndroid Build Coastguard Worker /* buffer phase */
978*e5436536SAndroid Build Coastguard Worker FDKmemcpy(self->PhasePrevLeft__FDK, self->PhaseLeft__FDK,
979*e5436536SAndroid Build Coastguard Worker self->numParameterBands * sizeof(FIXP_DBL));
980*e5436536SAndroid Build Coastguard Worker FDKmemcpy(self->PhasePrevRight__FDK, self->PhaseRight__FDK,
981*e5436536SAndroid Build Coastguard Worker self->numParameterBands * sizeof(FIXP_DBL));
982*e5436536SAndroid Build Coastguard Worker }
983*e5436536SAndroid Build Coastguard Worker
984*e5436536SAndroid Build Coastguard Worker #define PHASE_SCALE 2
985*e5436536SAndroid Build Coastguard Worker
986*e5436536SAndroid Build Coastguard Worker #ifndef P_PI
987*e5436536SAndroid Build Coastguard Worker #define P_PI 3.1415926535897932
988*e5436536SAndroid Build Coastguard Worker #endif
989*e5436536SAndroid Build Coastguard Worker
990*e5436536SAndroid Build Coastguard Worker /* For better precision, PI (pi_x2) is already doubled */
interp_angle__FDK(FIXP_DBL angle1,FIXP_DBL angle2,FIXP_SGL alpha,FIXP_DBL pi_x2)991*e5436536SAndroid Build Coastguard Worker static FIXP_DBL interp_angle__FDK(FIXP_DBL angle1, FIXP_DBL angle2,
992*e5436536SAndroid Build Coastguard Worker FIXP_SGL alpha, FIXP_DBL pi_x2) {
993*e5436536SAndroid Build Coastguard Worker if (angle2 - angle1 > (pi_x2 >> 1)) angle2 -= pi_x2;
994*e5436536SAndroid Build Coastguard Worker
995*e5436536SAndroid Build Coastguard Worker if (angle1 - angle2 > (pi_x2 >> 1)) angle1 -= pi_x2;
996*e5436536SAndroid Build Coastguard Worker
997*e5436536SAndroid Build Coastguard Worker return interpolateParameter(alpha, angle2, angle1);
998*e5436536SAndroid Build Coastguard Worker }
999*e5436536SAndroid Build Coastguard Worker
1000*e5436536SAndroid Build Coastguard Worker /*
1001*e5436536SAndroid Build Coastguard Worker *
1002*e5436536SAndroid Build Coastguard Worker */
SpatialDecApplyPhase(spatialDec * self,FIXP_SGL alpha__FDK,int lastSlotOfParamSet)1003*e5436536SAndroid Build Coastguard Worker void SpatialDecApplyPhase(spatialDec *self, FIXP_SGL alpha__FDK,
1004*e5436536SAndroid Build Coastguard Worker int lastSlotOfParamSet) {
1005*e5436536SAndroid Build Coastguard Worker int pb, qs;
1006*e5436536SAndroid Build Coastguard Worker FIXP_DBL ppb[MAX_PARAMETER_BANDS *
1007*e5436536SAndroid Build Coastguard Worker 4]; /* left real, imag - right real, imag interleaved */
1008*e5436536SAndroid Build Coastguard Worker
1009*e5436536SAndroid Build Coastguard Worker const FIXP_DBL pi_x2 = PIx2__IPD;
1010*e5436536SAndroid Build Coastguard Worker for (pb = 0; pb < self->numParameterBands; pb++) {
1011*e5436536SAndroid Build Coastguard Worker FIXP_DBL pl, pr;
1012*e5436536SAndroid Build Coastguard Worker
1013*e5436536SAndroid Build Coastguard Worker pl = interp_angle__FDK(self->PhasePrevLeft__FDK[pb],
1014*e5436536SAndroid Build Coastguard Worker self->PhaseLeft__FDK[pb], alpha__FDK, pi_x2);
1015*e5436536SAndroid Build Coastguard Worker pr = interp_angle__FDK(self->PhasePrevRight__FDK[pb],
1016*e5436536SAndroid Build Coastguard Worker self->PhaseRight__FDK[pb], alpha__FDK, pi_x2);
1017*e5436536SAndroid Build Coastguard Worker
1018*e5436536SAndroid Build Coastguard Worker inline_fixp_cos_sin(pl, pr, IPD_SCALE, &ppb[4 * pb]);
1019*e5436536SAndroid Build Coastguard Worker }
1020*e5436536SAndroid Build Coastguard Worker
1021*e5436536SAndroid Build Coastguard Worker /* sign is -1 for qs = 0,2 and +1 for qs = 1 */
1022*e5436536SAndroid Build Coastguard Worker
1023*e5436536SAndroid Build Coastguard Worker const SCHAR *kernels = &self->kernels[0];
1024*e5436536SAndroid Build Coastguard Worker
1025*e5436536SAndroid Build Coastguard Worker FIXP_DBL *Dry_real0 = &self->hybOutputRealDry__FDK[0][0];
1026*e5436536SAndroid Build Coastguard Worker FIXP_DBL *Dry_imag0 = &self->hybOutputImagDry__FDK[0][0];
1027*e5436536SAndroid Build Coastguard Worker FIXP_DBL *Dry_real1 = &self->hybOutputRealDry__FDK[1][0];
1028*e5436536SAndroid Build Coastguard Worker FIXP_DBL *Dry_imag1 = &self->hybOutputImagDry__FDK[1][0];
1029*e5436536SAndroid Build Coastguard Worker
1030*e5436536SAndroid Build Coastguard Worker for (qs = 2; qs >= 0; qs--) {
1031*e5436536SAndroid Build Coastguard Worker FIXP_DBL out_re, out_im;
1032*e5436536SAndroid Build Coastguard Worker
1033*e5436536SAndroid Build Coastguard Worker pb = *kernels++;
1034*e5436536SAndroid Build Coastguard Worker if (qs == 1) /* sign[qs] >= 0 */
1035*e5436536SAndroid Build Coastguard Worker {
1036*e5436536SAndroid Build Coastguard Worker cplxMultDiv2(&out_re, &out_im, *Dry_real0, *Dry_imag0, ppb[4 * pb + 0],
1037*e5436536SAndroid Build Coastguard Worker ppb[4 * pb + 1]);
1038*e5436536SAndroid Build Coastguard Worker out_re <<= PHASE_SCALE - 1;
1039*e5436536SAndroid Build Coastguard Worker out_im <<= PHASE_SCALE - 1;
1040*e5436536SAndroid Build Coastguard Worker *Dry_real0++ = out_re;
1041*e5436536SAndroid Build Coastguard Worker *Dry_imag0++ = out_im;
1042*e5436536SAndroid Build Coastguard Worker
1043*e5436536SAndroid Build Coastguard Worker cplxMultDiv2(&out_re, &out_im, *Dry_real1, *Dry_imag1, ppb[4 * pb + 2],
1044*e5436536SAndroid Build Coastguard Worker ppb[4 * pb + 3]);
1045*e5436536SAndroid Build Coastguard Worker out_re <<= PHASE_SCALE - 1;
1046*e5436536SAndroid Build Coastguard Worker out_im <<= PHASE_SCALE - 1;
1047*e5436536SAndroid Build Coastguard Worker *Dry_real1++ = out_re;
1048*e5436536SAndroid Build Coastguard Worker *Dry_imag1++ = out_im;
1049*e5436536SAndroid Build Coastguard Worker } else {
1050*e5436536SAndroid Build Coastguard Worker cplxMultDiv2(&out_re, &out_im, *Dry_real0, *Dry_imag0, ppb[4 * pb + 0],
1051*e5436536SAndroid Build Coastguard Worker -ppb[4 * pb + 1]);
1052*e5436536SAndroid Build Coastguard Worker out_re <<= PHASE_SCALE - 1;
1053*e5436536SAndroid Build Coastguard Worker out_im <<= PHASE_SCALE - 1;
1054*e5436536SAndroid Build Coastguard Worker *Dry_real0++ = out_re;
1055*e5436536SAndroid Build Coastguard Worker *Dry_imag0++ = out_im;
1056*e5436536SAndroid Build Coastguard Worker
1057*e5436536SAndroid Build Coastguard Worker cplxMultDiv2(&out_re, &out_im, *Dry_real1, *Dry_imag1, ppb[4 * pb + 2],
1058*e5436536SAndroid Build Coastguard Worker -ppb[4 * pb + 3]);
1059*e5436536SAndroid Build Coastguard Worker out_re <<= PHASE_SCALE - 1;
1060*e5436536SAndroid Build Coastguard Worker out_im <<= PHASE_SCALE - 1;
1061*e5436536SAndroid Build Coastguard Worker *Dry_real1++ = out_re;
1062*e5436536SAndroid Build Coastguard Worker *Dry_imag1++ = out_im;
1063*e5436536SAndroid Build Coastguard Worker }
1064*e5436536SAndroid Build Coastguard Worker }
1065*e5436536SAndroid Build Coastguard Worker
1066*e5436536SAndroid Build Coastguard Worker /* sign is +1 for qs >=3 */
1067*e5436536SAndroid Build Coastguard Worker for (qs = self->hybridBands - 3; qs--;) {
1068*e5436536SAndroid Build Coastguard Worker FIXP_DBL out_re, out_im;
1069*e5436536SAndroid Build Coastguard Worker
1070*e5436536SAndroid Build Coastguard Worker pb = *kernels++;
1071*e5436536SAndroid Build Coastguard Worker cplxMultDiv2(&out_re, &out_im, *Dry_real0, *Dry_imag0, ppb[4 * pb + 0],
1072*e5436536SAndroid Build Coastguard Worker ppb[4 * pb + 1]);
1073*e5436536SAndroid Build Coastguard Worker out_re <<= PHASE_SCALE - 1;
1074*e5436536SAndroid Build Coastguard Worker out_im <<= PHASE_SCALE - 1;
1075*e5436536SAndroid Build Coastguard Worker *Dry_real0++ = out_re;
1076*e5436536SAndroid Build Coastguard Worker *Dry_imag0++ = out_im;
1077*e5436536SAndroid Build Coastguard Worker
1078*e5436536SAndroid Build Coastguard Worker cplxMultDiv2(&out_re, &out_im, *Dry_real1, *Dry_imag1, ppb[4 * pb + 2],
1079*e5436536SAndroid Build Coastguard Worker ppb[4 * pb + 3]);
1080*e5436536SAndroid Build Coastguard Worker out_re <<= PHASE_SCALE - 1;
1081*e5436536SAndroid Build Coastguard Worker out_im <<= PHASE_SCALE - 1;
1082*e5436536SAndroid Build Coastguard Worker *Dry_real1++ = out_re;
1083*e5436536SAndroid Build Coastguard Worker *Dry_imag1++ = out_im;
1084*e5436536SAndroid Build Coastguard Worker }
1085*e5436536SAndroid Build Coastguard Worker }
1086