xref: /aosp_15_r20/external/aac/libFDK/src/FDK_hybrid.cpp (revision e54365361535b070c2db7374cec45c159c7d0e7a)
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 - 2020 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 /******************* Library for basic calculation routines ********************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):   Markus Lohwasser
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: FDK Tools Hybrid Filterbank
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "FDK_hybrid.h"
104*e5436536SAndroid Build Coastguard Worker 
105*e5436536SAndroid Build Coastguard Worker #include "fft.h"
106*e5436536SAndroid Build Coastguard Worker 
107*e5436536SAndroid Build Coastguard Worker /*--------------- defines -----------------------------*/
108*e5436536SAndroid Build Coastguard Worker #define FFT_IDX_R(a) (2 * a)
109*e5436536SAndroid Build Coastguard Worker #define FFT_IDX_I(a) (2 * a + 1)
110*e5436536SAndroid Build Coastguard Worker 
111*e5436536SAndroid Build Coastguard Worker #define HYB_COEF8_0 (0.00746082949812f)
112*e5436536SAndroid Build Coastguard Worker #define HYB_COEF8_1 (0.02270420949825f)
113*e5436536SAndroid Build Coastguard Worker #define HYB_COEF8_2 (0.04546865930473f)
114*e5436536SAndroid Build Coastguard Worker #define HYB_COEF8_3 (0.07266113929591f)
115*e5436536SAndroid Build Coastguard Worker #define HYB_COEF8_4 (0.09885108575264f)
116*e5436536SAndroid Build Coastguard Worker #define HYB_COEF8_5 (0.11793710567217f)
117*e5436536SAndroid Build Coastguard Worker #define HYB_COEF8_6 (0.12500000000000f)
118*e5436536SAndroid Build Coastguard Worker #define HYB_COEF8_7 (HYB_COEF8_5)
119*e5436536SAndroid Build Coastguard Worker #define HYB_COEF8_8 (HYB_COEF8_4)
120*e5436536SAndroid Build Coastguard Worker #define HYB_COEF8_9 (HYB_COEF8_3)
121*e5436536SAndroid Build Coastguard Worker #define HYB_COEF8_10 (HYB_COEF8_2)
122*e5436536SAndroid Build Coastguard Worker #define HYB_COEF8_11 (HYB_COEF8_1)
123*e5436536SAndroid Build Coastguard Worker #define HYB_COEF8_12 (HYB_COEF8_0)
124*e5436536SAndroid Build Coastguard Worker 
125*e5436536SAndroid Build Coastguard Worker /*--------------- structure definitions ---------------*/
126*e5436536SAndroid Build Coastguard Worker 
127*e5436536SAndroid Build Coastguard Worker #if defined(ARCH_PREFER_MULT_32x16)
128*e5436536SAndroid Build Coastguard Worker #define FIXP_HTB FIXP_SGL              /* SGL data type. */
129*e5436536SAndroid Build Coastguard Worker #define FIXP_HTP FIXP_SPK              /* Packed SGL data type. */
130*e5436536SAndroid Build Coastguard Worker #define HTC(a) (FX_DBL2FXCONST_SGL(a)) /* Cast to SGL */
131*e5436536SAndroid Build Coastguard Worker #define FL2FXCONST_HTB FL2FXCONST_SGL
132*e5436536SAndroid Build Coastguard Worker #else
133*e5436536SAndroid Build Coastguard Worker #define FIXP_HTB FIXP_DBL            /* SGL data type. */
134*e5436536SAndroid Build Coastguard Worker #define FIXP_HTP FIXP_DPK            /* Packed DBL data type. */
135*e5436536SAndroid Build Coastguard Worker #define HTC(a) ((FIXP_DBL)(LONG)(a)) /* Cast to DBL */
136*e5436536SAndroid Build Coastguard Worker #define FL2FXCONST_HTB FL2FXCONST_DBL
137*e5436536SAndroid Build Coastguard Worker #endif
138*e5436536SAndroid Build Coastguard Worker 
139*e5436536SAndroid Build Coastguard Worker #define HTCP(real, imag)     \
140*e5436536SAndroid Build Coastguard Worker   {                          \
141*e5436536SAndroid Build Coastguard Worker     { HTC(real), HTC(imag) } \
142*e5436536SAndroid Build Coastguard Worker   } /* How to arrange the packed values. */
143*e5436536SAndroid Build Coastguard Worker 
144*e5436536SAndroid Build Coastguard Worker struct FDK_HYBRID_SETUP {
145*e5436536SAndroid Build Coastguard Worker   UCHAR nrQmfBands;     /*!< Number of QMF bands to be converted to hybrid. */
146*e5436536SAndroid Build Coastguard Worker   UCHAR nHybBands[3];   /*!< Number of Hybrid bands generated by nrQmfBands. */
147*e5436536SAndroid Build Coastguard Worker   UCHAR synHybScale[3]; /*!< Headroom needed in hybrid synthesis filterbank. */
148*e5436536SAndroid Build Coastguard Worker   SCHAR kHybrid[3];     /*!< Filter configuration of each QMF band. */
149*e5436536SAndroid Build Coastguard Worker   UCHAR protoLen;       /*!< Prototype filter length. */
150*e5436536SAndroid Build Coastguard Worker   UCHAR filterDelay;    /*!< Delay caused by hybrid filter. */
151*e5436536SAndroid Build Coastguard Worker   const INT
152*e5436536SAndroid Build Coastguard Worker       *pReadIdxTable; /*!< Helper table to access input data ringbuffer. */
153*e5436536SAndroid Build Coastguard Worker };
154*e5436536SAndroid Build Coastguard Worker 
155*e5436536SAndroid Build Coastguard Worker /*--------------- constants ---------------------------*/
156*e5436536SAndroid Build Coastguard Worker static const INT ringbuffIdxTab[2 * 13] = {0, 1,  2,  3,  4, 5,  6,  7, 8,
157*e5436536SAndroid Build Coastguard Worker                                            9, 10, 11, 12, 0, 1,  2,  3, 4,
158*e5436536SAndroid Build Coastguard Worker                                            5, 6,  7,  8,  9, 10, 11, 12};
159*e5436536SAndroid Build Coastguard Worker 
160*e5436536SAndroid Build Coastguard Worker static const FDK_HYBRID_SETUP setup_3_16 = {
161*e5436536SAndroid Build Coastguard Worker     3, {8, 4, 4}, {4, 3, 3}, {8, 4, 4}, 13, (13 - 1) / 2, ringbuffIdxTab};
162*e5436536SAndroid Build Coastguard Worker static const FDK_HYBRID_SETUP setup_3_12 = {
163*e5436536SAndroid Build Coastguard Worker     3, {8, 2, 2}, {4, 2, 2}, {8, 2, 2}, 13, (13 - 1) / 2, ringbuffIdxTab};
164*e5436536SAndroid Build Coastguard Worker static const FDK_HYBRID_SETUP setup_3_10 = {
165*e5436536SAndroid Build Coastguard Worker     3, {6, 2, 2}, {3, 2, 2}, {-8, -2, 2}, 13, (13 - 1) / 2, ringbuffIdxTab};
166*e5436536SAndroid Build Coastguard Worker 
167*e5436536SAndroid Build Coastguard Worker static const FIXP_HTP HybFilterCoef8[] = {
168*e5436536SAndroid Build Coastguard Worker     HTCP(0x10000000, 0x00000000), HTCP(0x0df26407, 0xfa391882),
169*e5436536SAndroid Build Coastguard Worker     HTCP(0xff532109, 0x00acdef7), HTCP(0x08f26d36, 0xf70d92ca),
170*e5436536SAndroid Build Coastguard Worker     HTCP(0xfee34b5f, 0x02af570f), HTCP(0x038f276e, 0xf7684793),
171*e5436536SAndroid Build Coastguard Worker     HTCP(0x00000000, 0x05d1eac2), HTCP(0x00000000, 0x05d1eac2),
172*e5436536SAndroid Build Coastguard Worker     HTCP(0x038f276e, 0x0897b86d), HTCP(0xfee34b5f, 0xfd50a8f1),
173*e5436536SAndroid Build Coastguard Worker     HTCP(0x08f26d36, 0x08f26d36), HTCP(0xff532109, 0xff532109),
174*e5436536SAndroid Build Coastguard Worker     HTCP(0x0df26407, 0x05c6e77e)};
175*e5436536SAndroid Build Coastguard Worker 
176*e5436536SAndroid Build Coastguard Worker static const FIXP_HTB HybFilterCoef2[3] = {FL2FXCONST_HTB(0.01899487526049f),
177*e5436536SAndroid Build Coastguard Worker                                            FL2FXCONST_HTB(-0.07293139167538f),
178*e5436536SAndroid Build Coastguard Worker                                            FL2FXCONST_HTB(0.30596630545168f)};
179*e5436536SAndroid Build Coastguard Worker 
180*e5436536SAndroid Build Coastguard Worker static const FIXP_HTB HybFilterCoef4[13] = {FL2FXCONST_HTB(-0.00305151927305f),
181*e5436536SAndroid Build Coastguard Worker                                             FL2FXCONST_HTB(-0.00794862316203f),
182*e5436536SAndroid Build Coastguard Worker                                             FL2FXCONST_HTB(0.0f),
183*e5436536SAndroid Build Coastguard Worker                                             FL2FXCONST_HTB(0.04318924038756f),
184*e5436536SAndroid Build Coastguard Worker                                             FL2FXCONST_HTB(0.12542448210445f),
185*e5436536SAndroid Build Coastguard Worker                                             FL2FXCONST_HTB(0.21227807049160f),
186*e5436536SAndroid Build Coastguard Worker                                             FL2FXCONST_HTB(0.25f),
187*e5436536SAndroid Build Coastguard Worker                                             FL2FXCONST_HTB(0.21227807049160f),
188*e5436536SAndroid Build Coastguard Worker                                             FL2FXCONST_HTB(0.12542448210445f),
189*e5436536SAndroid Build Coastguard Worker                                             FL2FXCONST_HTB(0.04318924038756f),
190*e5436536SAndroid Build Coastguard Worker                                             FL2FXCONST_HTB(0.0f),
191*e5436536SAndroid Build Coastguard Worker                                             FL2FXCONST_HTB(-0.00794862316203f),
192*e5436536SAndroid Build Coastguard Worker                                             FL2FXCONST_HTB(-0.00305151927305f)};
193*e5436536SAndroid Build Coastguard Worker 
194*e5436536SAndroid Build Coastguard Worker /*--------------- function declarations ---------------*/
195*e5436536SAndroid Build Coastguard Worker static INT kChannelFiltering(const FIXP_DBL *const pQmfReal,
196*e5436536SAndroid Build Coastguard Worker                              const FIXP_DBL *const pQmfImag,
197*e5436536SAndroid Build Coastguard Worker                              const INT *const pReadIdx,
198*e5436536SAndroid Build Coastguard Worker                              FIXP_DBL *const mHybridReal,
199*e5436536SAndroid Build Coastguard Worker                              FIXP_DBL *const mHybridImag,
200*e5436536SAndroid Build Coastguard Worker                              const SCHAR hybridConfig);
201*e5436536SAndroid Build Coastguard Worker 
202*e5436536SAndroid Build Coastguard Worker /*--------------- function definitions ----------------*/
203*e5436536SAndroid Build Coastguard Worker 
FDKhybridAnalysisOpen(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,FIXP_DBL * const pLFmemory,const UINT LFmemorySize,FIXP_DBL * const pHFmemory,const UINT HFmemorySize)204*e5436536SAndroid Build Coastguard Worker INT FDKhybridAnalysisOpen(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
205*e5436536SAndroid Build Coastguard Worker                           FIXP_DBL *const pLFmemory, const UINT LFmemorySize,
206*e5436536SAndroid Build Coastguard Worker                           FIXP_DBL *const pHFmemory, const UINT HFmemorySize) {
207*e5436536SAndroid Build Coastguard Worker   INT err = 0;
208*e5436536SAndroid Build Coastguard Worker 
209*e5436536SAndroid Build Coastguard Worker   /* Save pointer to extern memory. */
210*e5436536SAndroid Build Coastguard Worker   hAnalysisHybFilter->pLFmemory = pLFmemory;
211*e5436536SAndroid Build Coastguard Worker   hAnalysisHybFilter->LFmemorySize = LFmemorySize;
212*e5436536SAndroid Build Coastguard Worker 
213*e5436536SAndroid Build Coastguard Worker   hAnalysisHybFilter->pHFmemory = pHFmemory;
214*e5436536SAndroid Build Coastguard Worker   hAnalysisHybFilter->HFmemorySize = HFmemorySize;
215*e5436536SAndroid Build Coastguard Worker 
216*e5436536SAndroid Build Coastguard Worker   return err;
217*e5436536SAndroid Build Coastguard Worker }
218*e5436536SAndroid Build Coastguard Worker 
FDKhybridAnalysisInit(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,const FDK_HYBRID_MODE mode,const INT qmfBands,const INT cplxBands,const INT initStatesFlag)219*e5436536SAndroid Build Coastguard Worker INT FDKhybridAnalysisInit(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
220*e5436536SAndroid Build Coastguard Worker                           const FDK_HYBRID_MODE mode, const INT qmfBands,
221*e5436536SAndroid Build Coastguard Worker                           const INT cplxBands, const INT initStatesFlag) {
222*e5436536SAndroid Build Coastguard Worker   int k;
223*e5436536SAndroid Build Coastguard Worker   INT err = 0;
224*e5436536SAndroid Build Coastguard Worker   FIXP_DBL *pMem = NULL;
225*e5436536SAndroid Build Coastguard Worker   HANDLE_FDK_HYBRID_SETUP setup = NULL;
226*e5436536SAndroid Build Coastguard Worker 
227*e5436536SAndroid Build Coastguard Worker   switch (mode) {
228*e5436536SAndroid Build Coastguard Worker     case THREE_TO_TEN:
229*e5436536SAndroid Build Coastguard Worker       setup = &setup_3_10;
230*e5436536SAndroid Build Coastguard Worker       break;
231*e5436536SAndroid Build Coastguard Worker     case THREE_TO_TWELVE:
232*e5436536SAndroid Build Coastguard Worker       setup = &setup_3_12;
233*e5436536SAndroid Build Coastguard Worker       break;
234*e5436536SAndroid Build Coastguard Worker     case THREE_TO_SIXTEEN:
235*e5436536SAndroid Build Coastguard Worker       setup = &setup_3_16;
236*e5436536SAndroid Build Coastguard Worker       break;
237*e5436536SAndroid Build Coastguard Worker     default:
238*e5436536SAndroid Build Coastguard Worker       err = -1;
239*e5436536SAndroid Build Coastguard Worker       goto bail;
240*e5436536SAndroid Build Coastguard Worker   }
241*e5436536SAndroid Build Coastguard Worker 
242*e5436536SAndroid Build Coastguard Worker   /* Initialize handle. */
243*e5436536SAndroid Build Coastguard Worker   hAnalysisHybFilter->pSetup = setup;
244*e5436536SAndroid Build Coastguard Worker   if (initStatesFlag) {
245*e5436536SAndroid Build Coastguard Worker     hAnalysisHybFilter->bufferLFpos = setup->protoLen - 1;
246*e5436536SAndroid Build Coastguard Worker     hAnalysisHybFilter->bufferHFpos = 0;
247*e5436536SAndroid Build Coastguard Worker   }
248*e5436536SAndroid Build Coastguard Worker   hAnalysisHybFilter->nrBands = qmfBands;
249*e5436536SAndroid Build Coastguard Worker   hAnalysisHybFilter->cplxBands = cplxBands;
250*e5436536SAndroid Build Coastguard Worker   hAnalysisHybFilter->hfMode = 0;
251*e5436536SAndroid Build Coastguard Worker 
252*e5436536SAndroid Build Coastguard Worker   /* Check available memory. */
253*e5436536SAndroid Build Coastguard Worker   if (((2 * setup->nrQmfBands * setup->protoLen * sizeof(FIXP_DBL)) >
254*e5436536SAndroid Build Coastguard Worker        hAnalysisHybFilter->LFmemorySize)) {
255*e5436536SAndroid Build Coastguard Worker     err = -2;
256*e5436536SAndroid Build Coastguard Worker     goto bail;
257*e5436536SAndroid Build Coastguard Worker   }
258*e5436536SAndroid Build Coastguard Worker   if (hAnalysisHybFilter->HFmemorySize != 0) {
259*e5436536SAndroid Build Coastguard Worker     if (((setup->filterDelay *
260*e5436536SAndroid Build Coastguard Worker           ((qmfBands - setup->nrQmfBands) + (cplxBands - setup->nrQmfBands)) *
261*e5436536SAndroid Build Coastguard Worker           sizeof(FIXP_DBL)) > hAnalysisHybFilter->HFmemorySize)) {
262*e5436536SAndroid Build Coastguard Worker       err = -3;
263*e5436536SAndroid Build Coastguard Worker       goto bail;
264*e5436536SAndroid Build Coastguard Worker     }
265*e5436536SAndroid Build Coastguard Worker   }
266*e5436536SAndroid Build Coastguard Worker 
267*e5436536SAndroid Build Coastguard Worker   /* Distribute LF memory. */
268*e5436536SAndroid Build Coastguard Worker   pMem = hAnalysisHybFilter->pLFmemory;
269*e5436536SAndroid Build Coastguard Worker   for (k = 0; k < setup->nrQmfBands; k++) {
270*e5436536SAndroid Build Coastguard Worker     hAnalysisHybFilter->bufferLFReal[k] = pMem;
271*e5436536SAndroid Build Coastguard Worker     pMem += setup->protoLen;
272*e5436536SAndroid Build Coastguard Worker     hAnalysisHybFilter->bufferLFImag[k] = pMem;
273*e5436536SAndroid Build Coastguard Worker     pMem += setup->protoLen;
274*e5436536SAndroid Build Coastguard Worker   }
275*e5436536SAndroid Build Coastguard Worker 
276*e5436536SAndroid Build Coastguard Worker   /* Distribute HF memory. */
277*e5436536SAndroid Build Coastguard Worker   if (hAnalysisHybFilter->HFmemorySize != 0) {
278*e5436536SAndroid Build Coastguard Worker     pMem = hAnalysisHybFilter->pHFmemory;
279*e5436536SAndroid Build Coastguard Worker     for (k = 0; k < setup->filterDelay; k++) {
280*e5436536SAndroid Build Coastguard Worker       hAnalysisHybFilter->bufferHFReal[k] = pMem;
281*e5436536SAndroid Build Coastguard Worker       pMem += (qmfBands - setup->nrQmfBands);
282*e5436536SAndroid Build Coastguard Worker       hAnalysisHybFilter->bufferHFImag[k] = pMem;
283*e5436536SAndroid Build Coastguard Worker       pMem += (cplxBands - setup->nrQmfBands);
284*e5436536SAndroid Build Coastguard Worker     }
285*e5436536SAndroid Build Coastguard Worker   }
286*e5436536SAndroid Build Coastguard Worker 
287*e5436536SAndroid Build Coastguard Worker   if (initStatesFlag) {
288*e5436536SAndroid Build Coastguard Worker     /* Clear LF buffer */
289*e5436536SAndroid Build Coastguard Worker     for (k = 0; k < setup->nrQmfBands; k++) {
290*e5436536SAndroid Build Coastguard Worker       FDKmemclear(hAnalysisHybFilter->bufferLFReal[k],
291*e5436536SAndroid Build Coastguard Worker                   setup->protoLen * sizeof(FIXP_DBL));
292*e5436536SAndroid Build Coastguard Worker       FDKmemclear(hAnalysisHybFilter->bufferLFImag[k],
293*e5436536SAndroid Build Coastguard Worker                   setup->protoLen * sizeof(FIXP_DBL));
294*e5436536SAndroid Build Coastguard Worker     }
295*e5436536SAndroid Build Coastguard Worker 
296*e5436536SAndroid Build Coastguard Worker     if (hAnalysisHybFilter->HFmemorySize != 0) {
297*e5436536SAndroid Build Coastguard Worker       if (qmfBands > setup->nrQmfBands) {
298*e5436536SAndroid Build Coastguard Worker         /* Clear HF buffer */
299*e5436536SAndroid Build Coastguard Worker         for (k = 0; k < setup->filterDelay; k++) {
300*e5436536SAndroid Build Coastguard Worker           FDKmemclear(hAnalysisHybFilter->bufferHFReal[k],
301*e5436536SAndroid Build Coastguard Worker                       (qmfBands - setup->nrQmfBands) * sizeof(FIXP_DBL));
302*e5436536SAndroid Build Coastguard Worker           FDKmemclear(hAnalysisHybFilter->bufferHFImag[k],
303*e5436536SAndroid Build Coastguard Worker                       (cplxBands - setup->nrQmfBands) * sizeof(FIXP_DBL));
304*e5436536SAndroid Build Coastguard Worker         }
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 bail:
310*e5436536SAndroid Build Coastguard Worker   return err;
311*e5436536SAndroid Build Coastguard Worker }
312*e5436536SAndroid Build Coastguard Worker 
FDKhybridAnalysisScaleStates(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,const INT scalingValue)313*e5436536SAndroid Build Coastguard Worker INT FDKhybridAnalysisScaleStates(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
314*e5436536SAndroid Build Coastguard Worker                                  const INT scalingValue) {
315*e5436536SAndroid Build Coastguard Worker   INT err = 0;
316*e5436536SAndroid Build Coastguard Worker 
317*e5436536SAndroid Build Coastguard Worker   if (hAnalysisHybFilter == NULL) {
318*e5436536SAndroid Build Coastguard Worker     err = 1; /* invalid handle */
319*e5436536SAndroid Build Coastguard Worker   } else {
320*e5436536SAndroid Build Coastguard Worker     int k;
321*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_HYBRID_SETUP setup = hAnalysisHybFilter->pSetup;
322*e5436536SAndroid Build Coastguard Worker 
323*e5436536SAndroid Build Coastguard Worker     /* Scale LF buffer */
324*e5436536SAndroid Build Coastguard Worker     for (k = 0; k < setup->nrQmfBands; k++) {
325*e5436536SAndroid Build Coastguard Worker       scaleValues(hAnalysisHybFilter->bufferLFReal[k], setup->protoLen,
326*e5436536SAndroid Build Coastguard Worker                   scalingValue);
327*e5436536SAndroid Build Coastguard Worker       scaleValues(hAnalysisHybFilter->bufferLFImag[k], setup->protoLen,
328*e5436536SAndroid Build Coastguard Worker                   scalingValue);
329*e5436536SAndroid Build Coastguard Worker     }
330*e5436536SAndroid Build Coastguard Worker     if (hAnalysisHybFilter->nrBands > setup->nrQmfBands) {
331*e5436536SAndroid Build Coastguard Worker       /* Scale HF buffer */
332*e5436536SAndroid Build Coastguard Worker       for (k = 0; k < setup->filterDelay; k++) {
333*e5436536SAndroid Build Coastguard Worker         scaleValues(hAnalysisHybFilter->bufferHFReal[k],
334*e5436536SAndroid Build Coastguard Worker                     (hAnalysisHybFilter->nrBands - setup->nrQmfBands),
335*e5436536SAndroid Build Coastguard Worker                     scalingValue);
336*e5436536SAndroid Build Coastguard Worker         scaleValues(hAnalysisHybFilter->bufferHFImag[k],
337*e5436536SAndroid Build Coastguard Worker                     (hAnalysisHybFilter->cplxBands - setup->nrQmfBands),
338*e5436536SAndroid Build Coastguard Worker                     scalingValue);
339*e5436536SAndroid Build Coastguard Worker       }
340*e5436536SAndroid Build Coastguard Worker     }
341*e5436536SAndroid Build Coastguard Worker   }
342*e5436536SAndroid Build Coastguard Worker   return err;
343*e5436536SAndroid Build Coastguard Worker }
344*e5436536SAndroid Build Coastguard Worker 
FDKhybridAnalysisApply(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,const FIXP_DBL * const pQmfReal,const FIXP_DBL * const pQmfImag,FIXP_DBL * const pHybridReal,FIXP_DBL * const pHybridImag)345*e5436536SAndroid Build Coastguard Worker INT FDKhybridAnalysisApply(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
346*e5436536SAndroid Build Coastguard Worker                            const FIXP_DBL *const pQmfReal,
347*e5436536SAndroid Build Coastguard Worker                            const FIXP_DBL *const pQmfImag,
348*e5436536SAndroid Build Coastguard Worker                            FIXP_DBL *const pHybridReal,
349*e5436536SAndroid Build Coastguard Worker                            FIXP_DBL *const pHybridImag) {
350*e5436536SAndroid Build Coastguard Worker   int k, hybOffset = 0;
351*e5436536SAndroid Build Coastguard Worker   INT err = 0;
352*e5436536SAndroid Build Coastguard Worker   const int nrQmfBandsLF =
353*e5436536SAndroid Build Coastguard Worker       hAnalysisHybFilter->pSetup
354*e5436536SAndroid Build Coastguard Worker           ->nrQmfBands; /* number of QMF bands to be converted to hybrid */
355*e5436536SAndroid Build Coastguard Worker 
356*e5436536SAndroid Build Coastguard Worker   const int writIndex = hAnalysisHybFilter->bufferLFpos;
357*e5436536SAndroid Build Coastguard Worker   int readIndex = hAnalysisHybFilter->bufferLFpos;
358*e5436536SAndroid Build Coastguard Worker 
359*e5436536SAndroid Build Coastguard Worker   if (++readIndex >= hAnalysisHybFilter->pSetup->protoLen) readIndex = 0;
360*e5436536SAndroid Build Coastguard Worker   const INT *pBufferLFreadIdx =
361*e5436536SAndroid Build Coastguard Worker       &hAnalysisHybFilter->pSetup->pReadIdxTable[readIndex];
362*e5436536SAndroid Build Coastguard Worker 
363*e5436536SAndroid Build Coastguard Worker   /*
364*e5436536SAndroid Build Coastguard Worker    * LF buffer.
365*e5436536SAndroid Build Coastguard Worker    */
366*e5436536SAndroid Build Coastguard Worker   for (k = 0; k < nrQmfBandsLF; k++) {
367*e5436536SAndroid Build Coastguard Worker     /* New input sample. */
368*e5436536SAndroid Build Coastguard Worker     hAnalysisHybFilter->bufferLFReal[k][writIndex] = pQmfReal[k];
369*e5436536SAndroid Build Coastguard Worker     hAnalysisHybFilter->bufferLFImag[k][writIndex] = pQmfImag[k];
370*e5436536SAndroid Build Coastguard Worker 
371*e5436536SAndroid Build Coastguard Worker     /* Perform hybrid filtering. */
372*e5436536SAndroid Build Coastguard Worker     err |=
373*e5436536SAndroid Build Coastguard Worker         kChannelFiltering(hAnalysisHybFilter->bufferLFReal[k],
374*e5436536SAndroid Build Coastguard Worker                           hAnalysisHybFilter->bufferLFImag[k], pBufferLFreadIdx,
375*e5436536SAndroid Build Coastguard Worker                           pHybridReal + hybOffset, pHybridImag + hybOffset,
376*e5436536SAndroid Build Coastguard Worker                           hAnalysisHybFilter->pSetup->kHybrid[k]);
377*e5436536SAndroid Build Coastguard Worker 
378*e5436536SAndroid Build Coastguard Worker     hybOffset += hAnalysisHybFilter->pSetup->nHybBands[k];
379*e5436536SAndroid Build Coastguard Worker   }
380*e5436536SAndroid Build Coastguard Worker 
381*e5436536SAndroid Build Coastguard Worker   hAnalysisHybFilter->bufferLFpos =
382*e5436536SAndroid Build Coastguard Worker       readIndex; /* Index where to write next input sample. */
383*e5436536SAndroid Build Coastguard Worker 
384*e5436536SAndroid Build Coastguard Worker   if (hAnalysisHybFilter->nrBands > nrQmfBandsLF) {
385*e5436536SAndroid Build Coastguard Worker     /*
386*e5436536SAndroid Build Coastguard Worker      * HF buffer.
387*e5436536SAndroid Build Coastguard Worker      */
388*e5436536SAndroid Build Coastguard Worker     if (hAnalysisHybFilter->hfMode != 0) {
389*e5436536SAndroid Build Coastguard Worker       /* HF delay compensation was applied outside. */
390*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(
391*e5436536SAndroid Build Coastguard Worker           pHybridReal + hybOffset, &pQmfReal[nrQmfBandsLF],
392*e5436536SAndroid Build Coastguard Worker           (hAnalysisHybFilter->nrBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
393*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(
394*e5436536SAndroid Build Coastguard Worker           pHybridImag + hybOffset, &pQmfImag[nrQmfBandsLF],
395*e5436536SAndroid Build Coastguard Worker           (hAnalysisHybFilter->cplxBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
396*e5436536SAndroid Build Coastguard Worker     } else {
397*e5436536SAndroid Build Coastguard Worker       FDK_ASSERT(hAnalysisHybFilter->HFmemorySize != 0);
398*e5436536SAndroid Build Coastguard Worker       /* HF delay compensation, filterlength/2. */
399*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(
400*e5436536SAndroid Build Coastguard Worker           pHybridReal + hybOffset,
401*e5436536SAndroid Build Coastguard Worker           hAnalysisHybFilter->bufferHFReal[hAnalysisHybFilter->bufferHFpos],
402*e5436536SAndroid Build Coastguard Worker           (hAnalysisHybFilter->nrBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
403*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(
404*e5436536SAndroid Build Coastguard Worker           pHybridImag + hybOffset,
405*e5436536SAndroid Build Coastguard Worker           hAnalysisHybFilter->bufferHFImag[hAnalysisHybFilter->bufferHFpos],
406*e5436536SAndroid Build Coastguard Worker           (hAnalysisHybFilter->cplxBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
407*e5436536SAndroid Build Coastguard Worker 
408*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(
409*e5436536SAndroid Build Coastguard Worker           hAnalysisHybFilter->bufferHFReal[hAnalysisHybFilter->bufferHFpos],
410*e5436536SAndroid Build Coastguard Worker           &pQmfReal[nrQmfBandsLF],
411*e5436536SAndroid Build Coastguard Worker           (hAnalysisHybFilter->nrBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
412*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(
413*e5436536SAndroid Build Coastguard Worker           hAnalysisHybFilter->bufferHFImag[hAnalysisHybFilter->bufferHFpos],
414*e5436536SAndroid Build Coastguard Worker           &pQmfImag[nrQmfBandsLF],
415*e5436536SAndroid Build Coastguard Worker           (hAnalysisHybFilter->cplxBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
416*e5436536SAndroid Build Coastguard Worker 
417*e5436536SAndroid Build Coastguard Worker       if (++hAnalysisHybFilter->bufferHFpos >=
418*e5436536SAndroid Build Coastguard Worker           hAnalysisHybFilter->pSetup->filterDelay)
419*e5436536SAndroid Build Coastguard Worker         hAnalysisHybFilter->bufferHFpos = 0;
420*e5436536SAndroid Build Coastguard Worker     }
421*e5436536SAndroid Build Coastguard Worker   } /* process HF part*/
422*e5436536SAndroid Build Coastguard Worker 
423*e5436536SAndroid Build Coastguard Worker   return err;
424*e5436536SAndroid Build Coastguard Worker }
425*e5436536SAndroid Build Coastguard Worker 
FDKhybridAnalysisClose(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter)426*e5436536SAndroid Build Coastguard Worker INT FDKhybridAnalysisClose(HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter) {
427*e5436536SAndroid Build Coastguard Worker   INT err = 0;
428*e5436536SAndroid Build Coastguard Worker 
429*e5436536SAndroid Build Coastguard Worker   if (hAnalysisHybFilter != NULL) {
430*e5436536SAndroid Build Coastguard Worker     hAnalysisHybFilter->pLFmemory = NULL;
431*e5436536SAndroid Build Coastguard Worker     hAnalysisHybFilter->pHFmemory = NULL;
432*e5436536SAndroid Build Coastguard Worker     hAnalysisHybFilter->LFmemorySize = 0;
433*e5436536SAndroid Build Coastguard Worker     hAnalysisHybFilter->HFmemorySize = 0;
434*e5436536SAndroid Build Coastguard Worker   }
435*e5436536SAndroid Build Coastguard Worker 
436*e5436536SAndroid Build Coastguard Worker   return err;
437*e5436536SAndroid Build Coastguard Worker }
438*e5436536SAndroid Build Coastguard Worker 
FDKhybridSynthesisInit(HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,const FDK_HYBRID_MODE mode,const INT qmfBands,const INT cplxBands)439*e5436536SAndroid Build Coastguard Worker INT FDKhybridSynthesisInit(HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,
440*e5436536SAndroid Build Coastguard Worker                            const FDK_HYBRID_MODE mode, const INT qmfBands,
441*e5436536SAndroid Build Coastguard Worker                            const INT cplxBands) {
442*e5436536SAndroid Build Coastguard Worker   INT err = 0;
443*e5436536SAndroid Build Coastguard Worker   HANDLE_FDK_HYBRID_SETUP setup = NULL;
444*e5436536SAndroid Build Coastguard Worker 
445*e5436536SAndroid Build Coastguard Worker   switch (mode) {
446*e5436536SAndroid Build Coastguard Worker     case THREE_TO_TEN:
447*e5436536SAndroid Build Coastguard Worker       setup = &setup_3_10;
448*e5436536SAndroid Build Coastguard Worker       break;
449*e5436536SAndroid Build Coastguard Worker     case THREE_TO_TWELVE:
450*e5436536SAndroid Build Coastguard Worker       setup = &setup_3_12;
451*e5436536SAndroid Build Coastguard Worker       break;
452*e5436536SAndroid Build Coastguard Worker     case THREE_TO_SIXTEEN:
453*e5436536SAndroid Build Coastguard Worker       setup = &setup_3_16;
454*e5436536SAndroid Build Coastguard Worker       break;
455*e5436536SAndroid Build Coastguard Worker     default:
456*e5436536SAndroid Build Coastguard Worker       err = -1;
457*e5436536SAndroid Build Coastguard Worker       goto bail;
458*e5436536SAndroid Build Coastguard Worker   }
459*e5436536SAndroid Build Coastguard Worker 
460*e5436536SAndroid Build Coastguard Worker   hSynthesisHybFilter->pSetup = setup;
461*e5436536SAndroid Build Coastguard Worker   hSynthesisHybFilter->nrBands = qmfBands;
462*e5436536SAndroid Build Coastguard Worker   hSynthesisHybFilter->cplxBands = cplxBands;
463*e5436536SAndroid Build Coastguard Worker 
464*e5436536SAndroid Build Coastguard Worker bail:
465*e5436536SAndroid Build Coastguard Worker   return err;
466*e5436536SAndroid Build Coastguard Worker }
467*e5436536SAndroid Build Coastguard Worker 
FDKhybridSynthesisApply(HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,const FIXP_DBL * const pHybridReal,const FIXP_DBL * const pHybridImag,FIXP_DBL * const pQmfReal,FIXP_DBL * const pQmfImag)468*e5436536SAndroid Build Coastguard Worker void FDKhybridSynthesisApply(HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,
469*e5436536SAndroid Build Coastguard Worker                              const FIXP_DBL *const pHybridReal,
470*e5436536SAndroid Build Coastguard Worker                              const FIXP_DBL *const pHybridImag,
471*e5436536SAndroid Build Coastguard Worker                              FIXP_DBL *const pQmfReal,
472*e5436536SAndroid Build Coastguard Worker                              FIXP_DBL *const pQmfImag) {
473*e5436536SAndroid Build Coastguard Worker   int k, n, hybOffset = 0;
474*e5436536SAndroid Build Coastguard Worker   const INT nrQmfBandsLF = hSynthesisHybFilter->pSetup->nrQmfBands;
475*e5436536SAndroid Build Coastguard Worker 
476*e5436536SAndroid Build Coastguard Worker   /*
477*e5436536SAndroid Build Coastguard Worker    * LF buffer.
478*e5436536SAndroid Build Coastguard Worker    */
479*e5436536SAndroid Build Coastguard Worker   for (k = 0; k < nrQmfBandsLF; k++) {
480*e5436536SAndroid Build Coastguard Worker     const int nHybBands = hSynthesisHybFilter->pSetup->nHybBands[k];
481*e5436536SAndroid Build Coastguard Worker     const int scale = hSynthesisHybFilter->pSetup->synHybScale[k];
482*e5436536SAndroid Build Coastguard Worker 
483*e5436536SAndroid Build Coastguard Worker     FIXP_DBL accu1 = FL2FXCONST_DBL(0.f);
484*e5436536SAndroid Build Coastguard Worker     FIXP_DBL accu2 = FL2FXCONST_DBL(0.f);
485*e5436536SAndroid Build Coastguard Worker 
486*e5436536SAndroid Build Coastguard Worker     /* Perform hybrid filtering. */
487*e5436536SAndroid Build Coastguard Worker     for (n = 0; n < nHybBands; n++) {
488*e5436536SAndroid Build Coastguard Worker       accu1 += pHybridReal[hybOffset + n] >> scale;
489*e5436536SAndroid Build Coastguard Worker       accu2 += pHybridImag[hybOffset + n] >> scale;
490*e5436536SAndroid Build Coastguard Worker     }
491*e5436536SAndroid Build Coastguard Worker     pQmfReal[k] = SATURATE_LEFT_SHIFT(accu1, scale, DFRACT_BITS);
492*e5436536SAndroid Build Coastguard Worker     pQmfImag[k] = SATURATE_LEFT_SHIFT(accu2, scale, DFRACT_BITS);
493*e5436536SAndroid Build Coastguard Worker 
494*e5436536SAndroid Build Coastguard Worker     hybOffset += nHybBands;
495*e5436536SAndroid Build Coastguard Worker   }
496*e5436536SAndroid Build Coastguard Worker 
497*e5436536SAndroid Build Coastguard Worker   if (hSynthesisHybFilter->nrBands > nrQmfBandsLF) {
498*e5436536SAndroid Build Coastguard Worker     /*
499*e5436536SAndroid Build Coastguard Worker      * HF buffer.
500*e5436536SAndroid Build Coastguard Worker      */
501*e5436536SAndroid Build Coastguard Worker     FDKmemcpy(&pQmfReal[nrQmfBandsLF], &pHybridReal[hybOffset],
502*e5436536SAndroid Build Coastguard Worker               (hSynthesisHybFilter->nrBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
503*e5436536SAndroid Build Coastguard Worker     FDKmemcpy(
504*e5436536SAndroid Build Coastguard Worker         &pQmfImag[nrQmfBandsLF], &pHybridImag[hybOffset],
505*e5436536SAndroid Build Coastguard Worker         (hSynthesisHybFilter->cplxBands - nrQmfBandsLF) * sizeof(FIXP_DBL));
506*e5436536SAndroid Build Coastguard Worker   }
507*e5436536SAndroid Build Coastguard Worker 
508*e5436536SAndroid Build Coastguard Worker   return;
509*e5436536SAndroid Build Coastguard Worker }
510*e5436536SAndroid Build Coastguard Worker 
dualChannelFiltering(const FIXP_DBL * const pQmfReal,const FIXP_DBL * const pQmfImag,const INT * const pReadIdx,FIXP_DBL * const mHybridReal,FIXP_DBL * const mHybridImag,const INT invert)511*e5436536SAndroid Build Coastguard Worker static void dualChannelFiltering(const FIXP_DBL *const pQmfReal,
512*e5436536SAndroid Build Coastguard Worker                                  const FIXP_DBL *const pQmfImag,
513*e5436536SAndroid Build Coastguard Worker                                  const INT *const pReadIdx,
514*e5436536SAndroid Build Coastguard Worker                                  FIXP_DBL *const mHybridReal,
515*e5436536SAndroid Build Coastguard Worker                                  FIXP_DBL *const mHybridImag,
516*e5436536SAndroid Build Coastguard Worker                                  const INT invert) {
517*e5436536SAndroid Build Coastguard Worker   FIXP_DBL r1, r6;
518*e5436536SAndroid Build Coastguard Worker   FIXP_DBL i1, i6;
519*e5436536SAndroid Build Coastguard Worker 
520*e5436536SAndroid Build Coastguard Worker   const FIXP_HTB f0 = HybFilterCoef2[0]; /* corresponds to p1 and p11 */
521*e5436536SAndroid Build Coastguard Worker   const FIXP_HTB f1 = HybFilterCoef2[1]; /* corresponds to p3 and p9  */
522*e5436536SAndroid Build Coastguard Worker   const FIXP_HTB f2 = HybFilterCoef2[2]; /* corresponds to p5 and p7  */
523*e5436536SAndroid Build Coastguard Worker 
524*e5436536SAndroid Build Coastguard Worker   /* symmetric filter coefficients */
525*e5436536SAndroid Build Coastguard Worker   r1 = fMultDiv2(f0, pQmfReal[pReadIdx[1]]) +
526*e5436536SAndroid Build Coastguard Worker        fMultDiv2(f0, pQmfReal[pReadIdx[11]]);
527*e5436536SAndroid Build Coastguard Worker   i1 = fMultDiv2(f0, pQmfImag[pReadIdx[1]]) +
528*e5436536SAndroid Build Coastguard Worker        fMultDiv2(f0, pQmfImag[pReadIdx[11]]);
529*e5436536SAndroid Build Coastguard Worker   r1 += fMultDiv2(f1, pQmfReal[pReadIdx[3]]) +
530*e5436536SAndroid Build Coastguard Worker         fMultDiv2(f1, pQmfReal[pReadIdx[9]]);
531*e5436536SAndroid Build Coastguard Worker   i1 += fMultDiv2(f1, pQmfImag[pReadIdx[3]]) +
532*e5436536SAndroid Build Coastguard Worker         fMultDiv2(f1, pQmfImag[pReadIdx[9]]);
533*e5436536SAndroid Build Coastguard Worker   r1 += fMultDiv2(f2, pQmfReal[pReadIdx[5]]) +
534*e5436536SAndroid Build Coastguard Worker         fMultDiv2(f2, pQmfReal[pReadIdx[7]]);
535*e5436536SAndroid Build Coastguard Worker   i1 += fMultDiv2(f2, pQmfImag[pReadIdx[5]]) +
536*e5436536SAndroid Build Coastguard Worker         fMultDiv2(f2, pQmfImag[pReadIdx[7]]);
537*e5436536SAndroid Build Coastguard Worker 
538*e5436536SAndroid Build Coastguard Worker   r6 = pQmfReal[pReadIdx[6]] >> 2;
539*e5436536SAndroid Build Coastguard Worker   i6 = pQmfImag[pReadIdx[6]] >> 2;
540*e5436536SAndroid Build Coastguard Worker 
541*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT((invert == 0) || (invert == 1));
542*e5436536SAndroid Build Coastguard Worker   mHybridReal[0 + invert] = SATURATE_LEFT_SHIFT((r6 + r1), 1, DFRACT_BITS);
543*e5436536SAndroid Build Coastguard Worker   mHybridImag[0 + invert] = SATURATE_LEFT_SHIFT((i6 + i1), 1, DFRACT_BITS);
544*e5436536SAndroid Build Coastguard Worker 
545*e5436536SAndroid Build Coastguard Worker   mHybridReal[1 - invert] = SATURATE_LEFT_SHIFT((r6 - r1), 1, DFRACT_BITS);
546*e5436536SAndroid Build Coastguard Worker   mHybridImag[1 - invert] = SATURATE_LEFT_SHIFT((i6 - i1), 1, DFRACT_BITS);
547*e5436536SAndroid Build Coastguard Worker }
548*e5436536SAndroid Build Coastguard Worker 
fourChannelFiltering(const FIXP_DBL * const pQmfReal,const FIXP_DBL * const pQmfImag,const INT * const pReadIdx,FIXP_DBL * const mHybridReal,FIXP_DBL * const mHybridImag,const INT invert)549*e5436536SAndroid Build Coastguard Worker static void fourChannelFiltering(const FIXP_DBL *const pQmfReal,
550*e5436536SAndroid Build Coastguard Worker                                  const FIXP_DBL *const pQmfImag,
551*e5436536SAndroid Build Coastguard Worker                                  const INT *const pReadIdx,
552*e5436536SAndroid Build Coastguard Worker                                  FIXP_DBL *const mHybridReal,
553*e5436536SAndroid Build Coastguard Worker                                  FIXP_DBL *const mHybridImag,
554*e5436536SAndroid Build Coastguard Worker                                  const INT invert) {
555*e5436536SAndroid Build Coastguard Worker   const FIXP_HTB *p = HybFilterCoef4;
556*e5436536SAndroid Build Coastguard Worker 
557*e5436536SAndroid Build Coastguard Worker   FIXP_DBL fft[8];
558*e5436536SAndroid Build Coastguard Worker 
559*e5436536SAndroid Build Coastguard Worker   static const FIXP_DBL cr[13] = {
560*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(0.f),  FL2FXCONST_DBL(-0.70710678118655f),
561*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(-1.f), FL2FXCONST_DBL(-0.70710678118655f),
562*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(0.f),  FL2FXCONST_DBL(0.70710678118655f),
563*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(1.f),  FL2FXCONST_DBL(0.70710678118655f),
564*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(0.f),  FL2FXCONST_DBL(-0.70710678118655f),
565*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(-1.f), FL2FXCONST_DBL(-0.70710678118655f),
566*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(0.f)};
567*e5436536SAndroid Build Coastguard Worker   static const FIXP_DBL ci[13] = {
568*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(-1.f), FL2FXCONST_DBL(-0.70710678118655f),
569*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(0.f),  FL2FXCONST_DBL(0.70710678118655f),
570*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(1.f),  FL2FXCONST_DBL(0.70710678118655f),
571*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(0.f),  FL2FXCONST_DBL(-0.70710678118655f),
572*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(-1.f), FL2FXCONST_DBL(-0.70710678118655f),
573*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(0.f),  FL2FXCONST_DBL(0.70710678118655f),
574*e5436536SAndroid Build Coastguard Worker       FL2FXCONST_DBL(1.f)};
575*e5436536SAndroid Build Coastguard Worker 
576*e5436536SAndroid Build Coastguard Worker   /* FIR filter. */
577*e5436536SAndroid Build Coastguard Worker   /* pre twiddeling with pre-twiddling coefficients c[n]  */
578*e5436536SAndroid Build Coastguard Worker   /* multiplication with filter coefficients p[n]         */
579*e5436536SAndroid Build Coastguard Worker   /* hint: (a + ib)*(c + id) = (a*c - b*d) + i(a*d + b*c) */
580*e5436536SAndroid Build Coastguard Worker   /* write to fft coefficient n'                          */
581*e5436536SAndroid Build Coastguard Worker   fft[FFT_IDX_R(0)] =
582*e5436536SAndroid Build Coastguard Worker       (fMult(p[10], (fMultSub(fMultDiv2(cr[2], pQmfReal[pReadIdx[2]]), ci[2],
583*e5436536SAndroid Build Coastguard Worker                               pQmfImag[pReadIdx[2]]))) +
584*e5436536SAndroid Build Coastguard Worker        fMult(p[6], (fMultSub(fMultDiv2(cr[6], pQmfReal[pReadIdx[6]]), ci[6],
585*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[6]]))) +
586*e5436536SAndroid Build Coastguard Worker        fMult(p[2], (fMultSub(fMultDiv2(cr[10], pQmfReal[pReadIdx[10]]), ci[10],
587*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[10]]))));
588*e5436536SAndroid Build Coastguard Worker   fft[FFT_IDX_I(0)] =
589*e5436536SAndroid Build Coastguard Worker       (fMult(p[10], (fMultAdd(fMultDiv2(ci[2], pQmfReal[pReadIdx[2]]), cr[2],
590*e5436536SAndroid Build Coastguard Worker                               pQmfImag[pReadIdx[2]]))) +
591*e5436536SAndroid Build Coastguard Worker        fMult(p[6], (fMultAdd(fMultDiv2(ci[6], pQmfReal[pReadIdx[6]]), cr[6],
592*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[6]]))) +
593*e5436536SAndroid Build Coastguard Worker        fMult(p[2], (fMultAdd(fMultDiv2(ci[10], pQmfReal[pReadIdx[10]]), cr[10],
594*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[10]]))));
595*e5436536SAndroid Build Coastguard Worker 
596*e5436536SAndroid Build Coastguard Worker   /* twiddle dee dum */
597*e5436536SAndroid Build Coastguard Worker   fft[FFT_IDX_R(1)] =
598*e5436536SAndroid Build Coastguard Worker       (fMult(p[9], (fMultSub(fMultDiv2(cr[3], pQmfReal[pReadIdx[3]]), ci[3],
599*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[3]]))) +
600*e5436536SAndroid Build Coastguard Worker        fMult(p[5], (fMultSub(fMultDiv2(cr[7], pQmfReal[pReadIdx[7]]), ci[7],
601*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[7]]))) +
602*e5436536SAndroid Build Coastguard Worker        fMult(p[1], (fMultSub(fMultDiv2(cr[11], pQmfReal[pReadIdx[11]]), ci[11],
603*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[11]]))));
604*e5436536SAndroid Build Coastguard Worker   fft[FFT_IDX_I(1)] =
605*e5436536SAndroid Build Coastguard Worker       (fMult(p[9], (fMultAdd(fMultDiv2(ci[3], pQmfReal[pReadIdx[3]]), cr[3],
606*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[3]]))) +
607*e5436536SAndroid Build Coastguard Worker        fMult(p[5], (fMultAdd(fMultDiv2(ci[7], pQmfReal[pReadIdx[7]]), cr[7],
608*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[7]]))) +
609*e5436536SAndroid Build Coastguard Worker        fMult(p[1], (fMultAdd(fMultDiv2(ci[11], pQmfReal[pReadIdx[11]]), cr[11],
610*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[11]]))));
611*e5436536SAndroid Build Coastguard Worker 
612*e5436536SAndroid Build Coastguard Worker   /* twiddle dee dee */
613*e5436536SAndroid Build Coastguard Worker   fft[FFT_IDX_R(2)] =
614*e5436536SAndroid Build Coastguard Worker       (fMult(p[12], (fMultSub(fMultDiv2(cr[0], pQmfReal[pReadIdx[0]]), ci[0],
615*e5436536SAndroid Build Coastguard Worker                               pQmfImag[pReadIdx[0]]))) +
616*e5436536SAndroid Build Coastguard Worker        fMult(p[8], (fMultSub(fMultDiv2(cr[4], pQmfReal[pReadIdx[4]]), ci[4],
617*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[4]]))) +
618*e5436536SAndroid Build Coastguard Worker        fMult(p[4], (fMultSub(fMultDiv2(cr[8], pQmfReal[pReadIdx[8]]), ci[8],
619*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[8]]))) +
620*e5436536SAndroid Build Coastguard Worker        fMult(p[0], (fMultSub(fMultDiv2(cr[12], pQmfReal[pReadIdx[12]]), ci[12],
621*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[12]]))));
622*e5436536SAndroid Build Coastguard Worker   fft[FFT_IDX_I(2)] =
623*e5436536SAndroid Build Coastguard Worker       (fMult(p[12], (fMultAdd(fMultDiv2(ci[0], pQmfReal[pReadIdx[0]]), cr[0],
624*e5436536SAndroid Build Coastguard Worker                               pQmfImag[pReadIdx[0]]))) +
625*e5436536SAndroid Build Coastguard Worker        fMult(p[8], (fMultAdd(fMultDiv2(ci[4], pQmfReal[pReadIdx[4]]), cr[4],
626*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[4]]))) +
627*e5436536SAndroid Build Coastguard Worker        fMult(p[4], (fMultAdd(fMultDiv2(ci[8], pQmfReal[pReadIdx[8]]), cr[8],
628*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[8]]))) +
629*e5436536SAndroid Build Coastguard Worker        fMult(p[0], (fMultAdd(fMultDiv2(ci[12], pQmfReal[pReadIdx[12]]), cr[12],
630*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[12]]))));
631*e5436536SAndroid Build Coastguard Worker 
632*e5436536SAndroid Build Coastguard Worker   fft[FFT_IDX_R(3)] =
633*e5436536SAndroid Build Coastguard Worker       (fMult(p[11], (fMultSub(fMultDiv2(cr[1], pQmfReal[pReadIdx[1]]), ci[1],
634*e5436536SAndroid Build Coastguard Worker                               pQmfImag[pReadIdx[1]]))) +
635*e5436536SAndroid Build Coastguard Worker        fMult(p[7], (fMultSub(fMultDiv2(cr[5], pQmfReal[pReadIdx[5]]), ci[5],
636*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[5]]))) +
637*e5436536SAndroid Build Coastguard Worker        fMult(p[3], (fMultSub(fMultDiv2(cr[9], pQmfReal[pReadIdx[9]]), ci[9],
638*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[9]]))));
639*e5436536SAndroid Build Coastguard Worker   fft[FFT_IDX_I(3)] =
640*e5436536SAndroid Build Coastguard Worker       (fMult(p[11], (fMultAdd(fMultDiv2(ci[1], pQmfReal[pReadIdx[1]]), cr[1],
641*e5436536SAndroid Build Coastguard Worker                               pQmfImag[pReadIdx[1]]))) +
642*e5436536SAndroid Build Coastguard Worker        fMult(p[7], (fMultAdd(fMultDiv2(ci[5], pQmfReal[pReadIdx[5]]), cr[5],
643*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[5]]))) +
644*e5436536SAndroid Build Coastguard Worker        fMult(p[3], (fMultAdd(fMultDiv2(ci[9], pQmfReal[pReadIdx[9]]), cr[9],
645*e5436536SAndroid Build Coastguard Worker                              pQmfImag[pReadIdx[9]]))));
646*e5436536SAndroid Build Coastguard Worker 
647*e5436536SAndroid Build Coastguard Worker   /* fft modulation                                                    */
648*e5436536SAndroid Build Coastguard Worker   /* here: fast manual fft modulation for a fft of length M=4          */
649*e5436536SAndroid Build Coastguard Worker   /* fft_4{x[n]} = x[0]*exp(-i*2*pi/4*m*0) + x[1]*exp(-i*2*pi/4*m*1) +
650*e5436536SAndroid Build Coastguard Worker   x[2]*exp(-i*2*pi/4*m*2) + x[3]*exp(-i*2*pi/4*m*3)   */
651*e5436536SAndroid Build Coastguard Worker 
652*e5436536SAndroid Build Coastguard Worker   /*
653*e5436536SAndroid Build Coastguard Worker   fft bin m=0:
654*e5436536SAndroid Build Coastguard Worker   X[0, n] = x[0] +   x[1] + x[2] +   x[3]
655*e5436536SAndroid Build Coastguard Worker   */
656*e5436536SAndroid Build Coastguard Worker   mHybridReal[0] = fft[FFT_IDX_R(0)] + fft[FFT_IDX_R(1)] + fft[FFT_IDX_R(2)] +
657*e5436536SAndroid Build Coastguard Worker                    fft[FFT_IDX_R(3)];
658*e5436536SAndroid Build Coastguard Worker   mHybridImag[0] = fft[FFT_IDX_I(0)] + fft[FFT_IDX_I(1)] + fft[FFT_IDX_I(2)] +
659*e5436536SAndroid Build Coastguard Worker                    fft[FFT_IDX_I(3)];
660*e5436536SAndroid Build Coastguard Worker 
661*e5436536SAndroid Build Coastguard Worker   /*
662*e5436536SAndroid Build Coastguard Worker   fft bin m=1:
663*e5436536SAndroid Build Coastguard Worker   X[1, n] = x[0] - i*x[1] - x[2] + i*x[3]
664*e5436536SAndroid Build Coastguard Worker   */
665*e5436536SAndroid Build Coastguard Worker   mHybridReal[1] = fft[FFT_IDX_R(0)] + fft[FFT_IDX_I(1)] - fft[FFT_IDX_R(2)] -
666*e5436536SAndroid Build Coastguard Worker                    fft[FFT_IDX_I(3)];
667*e5436536SAndroid Build Coastguard Worker   mHybridImag[1] = fft[FFT_IDX_I(0)] - fft[FFT_IDX_R(1)] - fft[FFT_IDX_I(2)] +
668*e5436536SAndroid Build Coastguard Worker                    fft[FFT_IDX_R(3)];
669*e5436536SAndroid Build Coastguard Worker 
670*e5436536SAndroid Build Coastguard Worker   /*
671*e5436536SAndroid Build Coastguard Worker   fft bin m=2:
672*e5436536SAndroid Build Coastguard Worker   X[2, n] = x[0] -   x[1] + x[2] -   x[3]
673*e5436536SAndroid Build Coastguard Worker   */
674*e5436536SAndroid Build Coastguard Worker   mHybridReal[2] = fft[FFT_IDX_R(0)] - fft[FFT_IDX_R(1)] + fft[FFT_IDX_R(2)] -
675*e5436536SAndroid Build Coastguard Worker                    fft[FFT_IDX_R(3)];
676*e5436536SAndroid Build Coastguard Worker   mHybridImag[2] = fft[FFT_IDX_I(0)] - fft[FFT_IDX_I(1)] + fft[FFT_IDX_I(2)] -
677*e5436536SAndroid Build Coastguard Worker                    fft[FFT_IDX_I(3)];
678*e5436536SAndroid Build Coastguard Worker 
679*e5436536SAndroid Build Coastguard Worker   /*
680*e5436536SAndroid Build Coastguard Worker   fft bin m=3:
681*e5436536SAndroid Build Coastguard Worker   X[3, n] = x[0] + j*x[1] - x[2] - j*x[3]
682*e5436536SAndroid Build Coastguard Worker   */
683*e5436536SAndroid Build Coastguard Worker   mHybridReal[3] = fft[FFT_IDX_R(0)] - fft[FFT_IDX_I(1)] - fft[FFT_IDX_R(2)] +
684*e5436536SAndroid Build Coastguard Worker                    fft[FFT_IDX_I(3)];
685*e5436536SAndroid Build Coastguard Worker   mHybridImag[3] = fft[FFT_IDX_I(0)] + fft[FFT_IDX_R(1)] - fft[FFT_IDX_I(2)] -
686*e5436536SAndroid Build Coastguard Worker                    fft[FFT_IDX_R(3)];
687*e5436536SAndroid Build Coastguard Worker }
688*e5436536SAndroid Build Coastguard Worker 
eightChannelFiltering(const FIXP_DBL * const pQmfReal,const FIXP_DBL * const pQmfImag,const INT * const pReadIdx,FIXP_DBL * const mHybridReal,FIXP_DBL * const mHybridImag,const INT invert)689*e5436536SAndroid Build Coastguard Worker static void eightChannelFiltering(const FIXP_DBL *const pQmfReal,
690*e5436536SAndroid Build Coastguard Worker                                   const FIXP_DBL *const pQmfImag,
691*e5436536SAndroid Build Coastguard Worker                                   const INT *const pReadIdx,
692*e5436536SAndroid Build Coastguard Worker                                   FIXP_DBL *const mHybridReal,
693*e5436536SAndroid Build Coastguard Worker                                   FIXP_DBL *const mHybridImag,
694*e5436536SAndroid Build Coastguard Worker                                   const INT invert) {
695*e5436536SAndroid Build Coastguard Worker   const FIXP_HTP *p = HybFilterCoef8;
696*e5436536SAndroid Build Coastguard Worker   INT k, sc;
697*e5436536SAndroid Build Coastguard Worker 
698*e5436536SAndroid Build Coastguard Worker   FIXP_DBL mfft[16 + ALIGNMENT_DEFAULT];
699*e5436536SAndroid Build Coastguard Worker   FIXP_DBL *pfft = (FIXP_DBL *)ALIGN_PTR(mfft);
700*e5436536SAndroid Build Coastguard Worker 
701*e5436536SAndroid Build Coastguard Worker   FIXP_DBL accu1, accu2, accu3, accu4;
702*e5436536SAndroid Build Coastguard Worker 
703*e5436536SAndroid Build Coastguard Worker   /* pre twiddeling */
704*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_R(0)] =
705*e5436536SAndroid Build Coastguard Worker       pQmfReal[pReadIdx[6]] >>
706*e5436536SAndroid Build Coastguard Worker       (3 + 1); /* fMultDiv2(p[0].v.re, pQmfReal[pReadIdx[6]]); */
707*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_I(0)] =
708*e5436536SAndroid Build Coastguard Worker       pQmfImag[pReadIdx[6]] >>
709*e5436536SAndroid Build Coastguard Worker       (3 + 1); /* fMultDiv2(p[0].v.re, pQmfImag[pReadIdx[6]]); */
710*e5436536SAndroid Build Coastguard Worker 
711*e5436536SAndroid Build Coastguard Worker   cplxMultDiv2(&accu1, &accu2, pQmfReal[pReadIdx[7]], pQmfImag[pReadIdx[7]],
712*e5436536SAndroid Build Coastguard Worker                p[1]);
713*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_R(1)] = accu1;
714*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_I(1)] = accu2;
715*e5436536SAndroid Build Coastguard Worker 
716*e5436536SAndroid Build Coastguard Worker   cplxMultDiv2(&accu1, &accu2, pQmfReal[pReadIdx[0]], pQmfImag[pReadIdx[0]],
717*e5436536SAndroid Build Coastguard Worker                p[2]);
718*e5436536SAndroid Build Coastguard Worker   cplxMultDiv2(&accu3, &accu4, pQmfReal[pReadIdx[8]], pQmfImag[pReadIdx[8]],
719*e5436536SAndroid Build Coastguard Worker                p[3]);
720*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_R(2)] = accu1 + accu3;
721*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_I(2)] = accu2 + accu4;
722*e5436536SAndroid Build Coastguard Worker 
723*e5436536SAndroid Build Coastguard Worker   cplxMultDiv2(&accu1, &accu2, pQmfReal[pReadIdx[1]], pQmfImag[pReadIdx[1]],
724*e5436536SAndroid Build Coastguard Worker                p[4]);
725*e5436536SAndroid Build Coastguard Worker   cplxMultDiv2(&accu3, &accu4, pQmfReal[pReadIdx[9]], pQmfImag[pReadIdx[9]],
726*e5436536SAndroid Build Coastguard Worker                p[5]);
727*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_R(3)] = accu1 + accu3;
728*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_I(3)] = accu2 + accu4;
729*e5436536SAndroid Build Coastguard Worker 
730*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_R(4)] = fMultDiv2(pQmfImag[pReadIdx[10]], p[7].v.im) -
731*e5436536SAndroid Build Coastguard Worker                        fMultDiv2(pQmfImag[pReadIdx[2]], p[6].v.im);
732*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_I(4)] = fMultDiv2(pQmfReal[pReadIdx[2]], p[6].v.im) -
733*e5436536SAndroid Build Coastguard Worker                        fMultDiv2(pQmfReal[pReadIdx[10]], p[7].v.im);
734*e5436536SAndroid Build Coastguard Worker 
735*e5436536SAndroid Build Coastguard Worker   cplxMultDiv2(&accu1, &accu2, pQmfReal[pReadIdx[3]], pQmfImag[pReadIdx[3]],
736*e5436536SAndroid Build Coastguard Worker                p[8]);
737*e5436536SAndroid Build Coastguard Worker   cplxMultDiv2(&accu3, &accu4, pQmfReal[pReadIdx[11]], pQmfImag[pReadIdx[11]],
738*e5436536SAndroid Build Coastguard Worker                p[9]);
739*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_R(5)] = accu1 + accu3;
740*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_I(5)] = accu2 + accu4;
741*e5436536SAndroid Build Coastguard Worker 
742*e5436536SAndroid Build Coastguard Worker   cplxMultDiv2(&accu1, &accu2, pQmfReal[pReadIdx[4]], pQmfImag[pReadIdx[4]],
743*e5436536SAndroid Build Coastguard Worker                p[10]);
744*e5436536SAndroid Build Coastguard Worker   cplxMultDiv2(&accu3, &accu4, pQmfReal[pReadIdx[12]], pQmfImag[pReadIdx[12]],
745*e5436536SAndroid Build Coastguard Worker                p[11]);
746*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_R(6)] = accu1 + accu3;
747*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_I(6)] = accu2 + accu4;
748*e5436536SAndroid Build Coastguard Worker 
749*e5436536SAndroid Build Coastguard Worker   cplxMultDiv2(&accu1, &accu2, pQmfReal[pReadIdx[5]], pQmfImag[pReadIdx[5]],
750*e5436536SAndroid Build Coastguard Worker                p[12]);
751*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_R(7)] = accu1;
752*e5436536SAndroid Build Coastguard Worker   pfft[FFT_IDX_I(7)] = accu2;
753*e5436536SAndroid Build Coastguard Worker 
754*e5436536SAndroid Build Coastguard Worker   /* fft modulation */
755*e5436536SAndroid Build Coastguard Worker   fft_8(pfft);
756*e5436536SAndroid Build Coastguard Worker   sc = 1 + 2;
757*e5436536SAndroid Build Coastguard Worker 
758*e5436536SAndroid Build Coastguard Worker   if (invert) {
759*e5436536SAndroid Build Coastguard Worker     mHybridReal[0] = pfft[FFT_IDX_R(7)] << sc;
760*e5436536SAndroid Build Coastguard Worker     mHybridImag[0] = pfft[FFT_IDX_I(7)] << sc;
761*e5436536SAndroid Build Coastguard Worker     mHybridReal[1] = pfft[FFT_IDX_R(0)] << sc;
762*e5436536SAndroid Build Coastguard Worker     mHybridImag[1] = pfft[FFT_IDX_I(0)] << sc;
763*e5436536SAndroid Build Coastguard Worker 
764*e5436536SAndroid Build Coastguard Worker     mHybridReal[2] = pfft[FFT_IDX_R(6)] << sc;
765*e5436536SAndroid Build Coastguard Worker     mHybridImag[2] = pfft[FFT_IDX_I(6)] << sc;
766*e5436536SAndroid Build Coastguard Worker     mHybridReal[3] = pfft[FFT_IDX_R(1)] << sc;
767*e5436536SAndroid Build Coastguard Worker     mHybridImag[3] = pfft[FFT_IDX_I(1)] << sc;
768*e5436536SAndroid Build Coastguard Worker 
769*e5436536SAndroid Build Coastguard Worker     mHybridReal[4] = SATURATE_LEFT_SHIFT(
770*e5436536SAndroid Build Coastguard Worker         (pfft[FFT_IDX_R(2)] + pfft[FFT_IDX_R(5)]), sc, DFRACT_BITS);
771*e5436536SAndroid Build Coastguard Worker     mHybridImag[4] = SATURATE_LEFT_SHIFT(
772*e5436536SAndroid Build Coastguard Worker         (pfft[FFT_IDX_I(2)] + pfft[FFT_IDX_I(5)]), sc, DFRACT_BITS);
773*e5436536SAndroid Build Coastguard Worker 
774*e5436536SAndroid Build Coastguard Worker     mHybridReal[5] = SATURATE_LEFT_SHIFT(
775*e5436536SAndroid Build Coastguard Worker         (pfft[FFT_IDX_R(3)] + pfft[FFT_IDX_R(4)]), sc, DFRACT_BITS);
776*e5436536SAndroid Build Coastguard Worker     mHybridImag[5] = SATURATE_LEFT_SHIFT(
777*e5436536SAndroid Build Coastguard Worker         (pfft[FFT_IDX_I(3)] + pfft[FFT_IDX_I(4)]), sc, DFRACT_BITS);
778*e5436536SAndroid Build Coastguard Worker   } else {
779*e5436536SAndroid Build Coastguard Worker     for (k = 0; k < 8; k++) {
780*e5436536SAndroid Build Coastguard Worker       mHybridReal[k] = pfft[FFT_IDX_R(k)] << sc;
781*e5436536SAndroid Build Coastguard Worker       mHybridImag[k] = pfft[FFT_IDX_I(k)] << sc;
782*e5436536SAndroid Build Coastguard Worker     }
783*e5436536SAndroid Build Coastguard Worker   }
784*e5436536SAndroid Build Coastguard Worker }
785*e5436536SAndroid Build Coastguard Worker 
kChannelFiltering(const FIXP_DBL * const pQmfReal,const FIXP_DBL * const pQmfImag,const INT * const pReadIdx,FIXP_DBL * const mHybridReal,FIXP_DBL * const mHybridImag,const SCHAR hybridConfig)786*e5436536SAndroid Build Coastguard Worker static INT kChannelFiltering(const FIXP_DBL *const pQmfReal,
787*e5436536SAndroid Build Coastguard Worker                              const FIXP_DBL *const pQmfImag,
788*e5436536SAndroid Build Coastguard Worker                              const INT *const pReadIdx,
789*e5436536SAndroid Build Coastguard Worker                              FIXP_DBL *const mHybridReal,
790*e5436536SAndroid Build Coastguard Worker                              FIXP_DBL *const mHybridImag,
791*e5436536SAndroid Build Coastguard Worker                              const SCHAR hybridConfig) {
792*e5436536SAndroid Build Coastguard Worker   INT err = 0;
793*e5436536SAndroid Build Coastguard Worker 
794*e5436536SAndroid Build Coastguard Worker   switch (hybridConfig) {
795*e5436536SAndroid Build Coastguard Worker     case 2:
796*e5436536SAndroid Build Coastguard Worker     case -2:
797*e5436536SAndroid Build Coastguard Worker       dualChannelFiltering(pQmfReal, pQmfImag, pReadIdx, mHybridReal,
798*e5436536SAndroid Build Coastguard Worker                            mHybridImag, (hybridConfig < 0) ? 1 : 0);
799*e5436536SAndroid Build Coastguard Worker       break;
800*e5436536SAndroid Build Coastguard Worker     case 4:
801*e5436536SAndroid Build Coastguard Worker     case -4:
802*e5436536SAndroid Build Coastguard Worker       fourChannelFiltering(pQmfReal, pQmfImag, pReadIdx, mHybridReal,
803*e5436536SAndroid Build Coastguard Worker                            mHybridImag, (hybridConfig < 0) ? 1 : 0);
804*e5436536SAndroid Build Coastguard Worker       break;
805*e5436536SAndroid Build Coastguard Worker     case 8:
806*e5436536SAndroid Build Coastguard Worker     case -8:
807*e5436536SAndroid Build Coastguard Worker       eightChannelFiltering(pQmfReal, pQmfImag, pReadIdx, mHybridReal,
808*e5436536SAndroid Build Coastguard Worker                             mHybridImag, (hybridConfig < 0) ? 1 : 0);
809*e5436536SAndroid Build Coastguard Worker       break;
810*e5436536SAndroid Build Coastguard Worker     default:
811*e5436536SAndroid Build Coastguard Worker       err = -1;
812*e5436536SAndroid Build Coastguard Worker   }
813*e5436536SAndroid Build Coastguard Worker 
814*e5436536SAndroid Build Coastguard Worker   return err;
815*e5436536SAndroid Build Coastguard Worker }
816