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