xref: /aosp_15_r20/external/aac/libFDK/src/FDK_qmf_domain.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 - 2019 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):   Matthias Hildenbrand
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: Module to efficiently handle QMF data for multiple channels and
100*e5436536SAndroid Build Coastguard Worker                 to share the data between e.g. SBR and MPS
101*e5436536SAndroid Build Coastguard Worker 
102*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
103*e5436536SAndroid Build Coastguard Worker 
104*e5436536SAndroid Build Coastguard Worker #include "FDK_qmf_domain.h"
105*e5436536SAndroid Build Coastguard Worker 
106*e5436536SAndroid Build Coastguard Worker #include "common_fix.h"
107*e5436536SAndroid Build Coastguard Worker 
108*e5436536SAndroid Build Coastguard Worker #define WORKBUFFER1_TAG 0
109*e5436536SAndroid Build Coastguard Worker #define WORKBUFFER3_TAG 4
110*e5436536SAndroid Build Coastguard Worker #define WORKBUFFER4_TAG 5
111*e5436536SAndroid Build Coastguard Worker #define WORKBUFFER6_TAG 7
112*e5436536SAndroid Build Coastguard Worker #define WORKBUFFER7_TAG 8
113*e5436536SAndroid Build Coastguard Worker 
C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1,FIXP_DBL,QMF_WB_SECTION_SIZE,SECT_DATA_L1,WORKBUFFER1_TAG)114*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL, QMF_WB_SECTION_SIZE,
115*e5436536SAndroid Build Coastguard Worker                     SECT_DATA_L1, WORKBUFFER1_TAG)
116*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL, QMF_WB_SECTION_SIZE,
117*e5436536SAndroid Build Coastguard Worker                     SECT_DATA_L2, WORKBUFFER3_TAG)
118*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL, QMF_WB_SECTION_SIZE,
119*e5436536SAndroid Build Coastguard Worker                     SECT_DATA_L2, WORKBUFFER4_TAG)
120*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL, QMF_WB_SECTION_SIZE,
121*e5436536SAndroid Build Coastguard Worker                     SECT_DATA_L2, WORKBUFFER6_TAG)
122*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore7, FIXP_DBL, QMF_WB_SECTION_SIZE,
123*e5436536SAndroid Build Coastguard Worker                     SECT_DATA_L2, WORKBUFFER7_TAG)
124*e5436536SAndroid Build Coastguard Worker 
125*e5436536SAndroid Build Coastguard Worker /*! Analysis states buffer. <br>
126*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                   */
127*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(AnaQmfStates, FIXP_DBL, 10 * QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS,
128*e5436536SAndroid Build Coastguard Worker               ((8) + (1)))
129*e5436536SAndroid Build Coastguard Worker 
130*e5436536SAndroid Build Coastguard Worker /*! Synthesis states buffer. <br>
131*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                  */
132*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(SynQmfStates, FIXP_QSS, 9 * QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS,
133*e5436536SAndroid Build Coastguard Worker               ((8) + (1)))
134*e5436536SAndroid Build Coastguard Worker 
135*e5436536SAndroid Build Coastguard Worker /*! Pointer to real qmf data for each time slot. <br>
136*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                   */
137*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM2(QmfSlotsReal, FIXP_DBL *,
138*e5436536SAndroid Build Coastguard Worker              QMF_DOMAIN_MAX_TIMESLOTS + QMF_DOMAIN_MAX_OV_TIMESLOTS,
139*e5436536SAndroid Build Coastguard Worker              ((8) + (1)))
140*e5436536SAndroid Build Coastguard Worker 
141*e5436536SAndroid Build Coastguard Worker /*! Pointer to imaginary qmf data for each time slot. <br>
142*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                   */
143*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM2(QmfSlotsImag, FIXP_DBL *,
144*e5436536SAndroid Build Coastguard Worker              QMF_DOMAIN_MAX_TIMESLOTS + QMF_DOMAIN_MAX_OV_TIMESLOTS,
145*e5436536SAndroid Build Coastguard Worker              ((8) + (1)))
146*e5436536SAndroid Build Coastguard Worker 
147*e5436536SAndroid Build Coastguard Worker /*! QMF overlap buffer. <br>
148*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                   */
149*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(QmfOverlapBuffer, FIXP_DBL,
150*e5436536SAndroid Build Coastguard Worker               2 * QMF_DOMAIN_MAX_OV_TIMESLOTS * QMF_DOMAIN_MAX_QMF_PROC_BANDS,
151*e5436536SAndroid Build Coastguard Worker               ((8) + (1)))
152*e5436536SAndroid Build Coastguard Worker 
153*e5436536SAndroid Build Coastguard Worker /*! Analysis states buffer. <br>
154*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                   */
155*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(AnaQmfStates16, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_16,
156*e5436536SAndroid Build Coastguard Worker               ((8) + (1)))
157*e5436536SAndroid Build Coastguard Worker /*! Analysis states buffer. <br>
158*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                   */
159*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(AnaQmfStates24, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_24,
160*e5436536SAndroid Build Coastguard Worker               ((8) + (1)))
161*e5436536SAndroid Build Coastguard Worker 
162*e5436536SAndroid Build Coastguard Worker /*! Analysis states buffer. <br>
163*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                   */
164*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(AnaQmfStates32, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32,
165*e5436536SAndroid Build Coastguard Worker               ((8) + (1)))
166*e5436536SAndroid Build Coastguard Worker 
167*e5436536SAndroid Build Coastguard Worker /*! Pointer to real qmf data for each time slot. <br>
168*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                   */
169*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM2(QmfSlotsReal16, FIXP_DBL *,
170*e5436536SAndroid Build Coastguard Worker              QMF_DOMAIN_TIMESLOTS_16 + QMF_DOMAIN_OV_TIMESLOTS_16, ((8) + (1)))
171*e5436536SAndroid Build Coastguard Worker 
172*e5436536SAndroid Build Coastguard Worker /*! Pointer to real qmf data for each time slot. <br>
173*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                   */
174*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM2(QmfSlotsReal32, FIXP_DBL *,
175*e5436536SAndroid Build Coastguard Worker              QMF_DOMAIN_TIMESLOTS_32 + QMF_DOMAIN_OV_TIMESLOTS_32, ((8) + (1)))
176*e5436536SAndroid Build Coastguard Worker 
177*e5436536SAndroid Build Coastguard Worker /*! Pointer to imaginary qmf data for each time slot. <br>
178*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                   */
179*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM2(QmfSlotsImag16, FIXP_DBL *,
180*e5436536SAndroid Build Coastguard Worker              QMF_DOMAIN_TIMESLOTS_16 + QMF_DOMAIN_OV_TIMESLOTS_16, ((8) + (1)))
181*e5436536SAndroid Build Coastguard Worker 
182*e5436536SAndroid Build Coastguard Worker /*! Pointer to imaginary qmf data for each time slot. <br>
183*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                   */
184*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM2(QmfSlotsImag32, FIXP_DBL *,
185*e5436536SAndroid Build Coastguard Worker              QMF_DOMAIN_TIMESLOTS_32 + QMF_DOMAIN_OV_TIMESLOTS_32, ((8) + (1)))
186*e5436536SAndroid Build Coastguard Worker 
187*e5436536SAndroid Build Coastguard Worker /*! QMF overlap buffer. <br>
188*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                   */
189*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(QmfOverlapBuffer16, FIXP_DBL,
190*e5436536SAndroid Build Coastguard Worker               2 * QMF_DOMAIN_OV_TIMESLOTS_16 * QMF_DOMAIN_MAX_QMF_PROC_BANDS,
191*e5436536SAndroid Build Coastguard Worker               ((8) + (1)))
192*e5436536SAndroid Build Coastguard Worker 
193*e5436536SAndroid Build Coastguard Worker /*! QMF overlap buffer. <br>
194*e5436536SAndroid Build Coastguard Worker     Dimension: #((8) + (1))                                                   */
195*e5436536SAndroid Build Coastguard Worker C_AALLOC_MEM2(QmfOverlapBuffer32, FIXP_DBL,
196*e5436536SAndroid Build Coastguard Worker               2 * QMF_DOMAIN_OV_TIMESLOTS_32 * QMF_DOMAIN_MAX_QMF_PROC_BANDS,
197*e5436536SAndroid Build Coastguard Worker               ((8) + (1)))
198*e5436536SAndroid Build Coastguard Worker 
199*e5436536SAndroid Build Coastguard Worker static int FDK_QmfDomain_FreePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) {
200*e5436536SAndroid Build Coastguard Worker   int err = 0;
201*e5436536SAndroid Build Coastguard Worker   int ch;
202*e5436536SAndroid Build Coastguard Worker 
203*e5436536SAndroid Build Coastguard Worker   for (ch = 0; ch < ((8) + (1)); ch++) {
204*e5436536SAndroid Build Coastguard Worker     if (qd->QmfDomainIn[ch].pAnaQmfStates) {
205*e5436536SAndroid Build Coastguard Worker       if (qd->globalConf.nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_16) {
206*e5436536SAndroid Build Coastguard Worker         FreeAnaQmfStates16(&qd->QmfDomainIn[ch].pAnaQmfStates);
207*e5436536SAndroid Build Coastguard Worker       } else if (qd->globalConf.nBandsAnalysis ==
208*e5436536SAndroid Build Coastguard Worker                  QMF_DOMAIN_ANALYSIS_QMF_BANDS_24) {
209*e5436536SAndroid Build Coastguard Worker         FreeAnaQmfStates24(&qd->QmfDomainIn[ch].pAnaQmfStates);
210*e5436536SAndroid Build Coastguard Worker       } else if (qd->globalConf.nBandsAnalysis ==
211*e5436536SAndroid Build Coastguard Worker                  QMF_DOMAIN_ANALYSIS_QMF_BANDS_32) {
212*e5436536SAndroid Build Coastguard Worker         FreeAnaQmfStates32(&qd->QmfDomainIn[ch].pAnaQmfStates);
213*e5436536SAndroid Build Coastguard Worker       } else {
214*e5436536SAndroid Build Coastguard Worker         FreeAnaQmfStates(&qd->QmfDomainIn[ch].pAnaQmfStates);
215*e5436536SAndroid Build Coastguard Worker       }
216*e5436536SAndroid Build Coastguard Worker     }
217*e5436536SAndroid Build Coastguard Worker 
218*e5436536SAndroid Build Coastguard Worker     if (qd->QmfDomainIn[ch].pOverlapBuffer) {
219*e5436536SAndroid Build Coastguard Worker       if (qd->globalConf.nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_16) {
220*e5436536SAndroid Build Coastguard Worker         FreeQmfOverlapBuffer16(&qd->QmfDomainIn[ch].pOverlapBuffer);
221*e5436536SAndroid Build Coastguard Worker       } else if (qd->globalConf.nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_32) {
222*e5436536SAndroid Build Coastguard Worker         FreeQmfOverlapBuffer32(&qd->QmfDomainIn[ch].pOverlapBuffer);
223*e5436536SAndroid Build Coastguard Worker       } else {
224*e5436536SAndroid Build Coastguard Worker         FreeQmfOverlapBuffer(&qd->QmfDomainIn[ch].pOverlapBuffer);
225*e5436536SAndroid Build Coastguard Worker       }
226*e5436536SAndroid Build Coastguard Worker     }
227*e5436536SAndroid Build Coastguard Worker 
228*e5436536SAndroid Build Coastguard Worker     if (qd->QmfDomainIn[ch].hQmfSlotsReal) {
229*e5436536SAndroid Build Coastguard Worker       if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) {
230*e5436536SAndroid Build Coastguard Worker         FreeQmfSlotsReal16(&qd->QmfDomainIn[ch].hQmfSlotsReal);
231*e5436536SAndroid Build Coastguard Worker       } else if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) {
232*e5436536SAndroid Build Coastguard Worker         FreeQmfSlotsReal32(&qd->QmfDomainIn[ch].hQmfSlotsReal);
233*e5436536SAndroid Build Coastguard Worker       } else {
234*e5436536SAndroid Build Coastguard Worker         FreeQmfSlotsReal(&qd->QmfDomainIn[ch].hQmfSlotsReal);
235*e5436536SAndroid Build Coastguard Worker       }
236*e5436536SAndroid Build Coastguard Worker     }
237*e5436536SAndroid Build Coastguard Worker 
238*e5436536SAndroid Build Coastguard Worker     if (qd->QmfDomainIn[ch].hQmfSlotsImag) {
239*e5436536SAndroid Build Coastguard Worker       if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) {
240*e5436536SAndroid Build Coastguard Worker         FreeQmfSlotsImag16(&qd->QmfDomainIn[ch].hQmfSlotsImag);
241*e5436536SAndroid Build Coastguard Worker       }
242*e5436536SAndroid Build Coastguard Worker       if (qd->globalConf.nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) {
243*e5436536SAndroid Build Coastguard Worker         FreeQmfSlotsImag32(&qd->QmfDomainIn[ch].hQmfSlotsImag);
244*e5436536SAndroid Build Coastguard Worker       } else {
245*e5436536SAndroid Build Coastguard Worker         FreeQmfSlotsImag(&qd->QmfDomainIn[ch].hQmfSlotsImag);
246*e5436536SAndroid Build Coastguard Worker       }
247*e5436536SAndroid Build Coastguard Worker     }
248*e5436536SAndroid Build Coastguard Worker   }
249*e5436536SAndroid Build Coastguard Worker 
250*e5436536SAndroid Build Coastguard Worker   for (ch = 0; ch < ((8) + (1)); ch++) {
251*e5436536SAndroid Build Coastguard Worker     if (qd->QmfDomainOut[ch].pSynQmfStates) {
252*e5436536SAndroid Build Coastguard Worker       FreeSynQmfStates(&qd->QmfDomainOut[ch].pSynQmfStates);
253*e5436536SAndroid Build Coastguard Worker     }
254*e5436536SAndroid Build Coastguard Worker   }
255*e5436536SAndroid Build Coastguard Worker 
256*e5436536SAndroid Build Coastguard Worker   return err;
257*e5436536SAndroid Build Coastguard Worker }
258*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd)259*e5436536SAndroid Build Coastguard Worker static int FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) {
260*e5436536SAndroid Build Coastguard Worker   int err = 0;
261*e5436536SAndroid Build Coastguard Worker   int ch;
262*e5436536SAndroid Build Coastguard Worker   HANDLE_FDK_QMF_DOMAIN_GC gc = &qd->globalConf;
263*e5436536SAndroid Build Coastguard Worker 
264*e5436536SAndroid Build Coastguard Worker   if ((gc->nInputChannels > ((8) + (1))) || (gc->nOutputChannels > ((8) + (1))))
265*e5436536SAndroid Build Coastguard Worker     return err = 1;
266*e5436536SAndroid Build Coastguard Worker   for (ch = 0; ch < gc->nInputChannels; ch++) {
267*e5436536SAndroid Build Coastguard Worker     int size;
268*e5436536SAndroid Build Coastguard Worker 
269*e5436536SAndroid Build Coastguard Worker     size = gc->nBandsAnalysis * 10;
270*e5436536SAndroid Build Coastguard Worker     if (size > 0) {
271*e5436536SAndroid Build Coastguard Worker       if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_16) {
272*e5436536SAndroid Build Coastguard Worker         if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
273*e5436536SAndroid Build Coastguard Worker           if (NULL ==
274*e5436536SAndroid Build Coastguard Worker               (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates16(ch)))
275*e5436536SAndroid Build Coastguard Worker             goto bail;
276*e5436536SAndroid Build Coastguard Worker         }
277*e5436536SAndroid Build Coastguard Worker       } else if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_24) {
278*e5436536SAndroid Build Coastguard Worker         if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
279*e5436536SAndroid Build Coastguard Worker           if (NULL ==
280*e5436536SAndroid Build Coastguard Worker               (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates24(ch)))
281*e5436536SAndroid Build Coastguard Worker             goto bail;
282*e5436536SAndroid Build Coastguard Worker         }
283*e5436536SAndroid Build Coastguard Worker       } else if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_32) {
284*e5436536SAndroid Build Coastguard Worker         if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
285*e5436536SAndroid Build Coastguard Worker           if (NULL ==
286*e5436536SAndroid Build Coastguard Worker               (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates32(ch)))
287*e5436536SAndroid Build Coastguard Worker             goto bail;
288*e5436536SAndroid Build Coastguard Worker         }
289*e5436536SAndroid Build Coastguard Worker       } else {
290*e5436536SAndroid Build Coastguard Worker         if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) {
291*e5436536SAndroid Build Coastguard Worker           if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates(ch)))
292*e5436536SAndroid Build Coastguard Worker             goto bail;
293*e5436536SAndroid Build Coastguard Worker         }
294*e5436536SAndroid Build Coastguard Worker       }
295*e5436536SAndroid Build Coastguard Worker     } else {
296*e5436536SAndroid Build Coastguard Worker       qd->QmfDomainIn[ch].pAnaQmfStates = NULL;
297*e5436536SAndroid Build Coastguard Worker     }
298*e5436536SAndroid Build Coastguard Worker 
299*e5436536SAndroid Build Coastguard Worker     size = gc->nQmfOvTimeSlots + gc->nQmfTimeSlots;
300*e5436536SAndroid Build Coastguard Worker     if (size > 0) {
301*e5436536SAndroid Build Coastguard Worker       if (gc->nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) {
302*e5436536SAndroid Build Coastguard Worker         if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) {
303*e5436536SAndroid Build Coastguard Worker           if (NULL ==
304*e5436536SAndroid Build Coastguard Worker               (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal16(ch)))
305*e5436536SAndroid Build Coastguard Worker             goto bail;
306*e5436536SAndroid Build Coastguard Worker         }
307*e5436536SAndroid Build Coastguard Worker         if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) {
308*e5436536SAndroid Build Coastguard Worker           if (NULL ==
309*e5436536SAndroid Build Coastguard Worker               (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag16(ch)))
310*e5436536SAndroid Build Coastguard Worker             goto bail;
311*e5436536SAndroid Build Coastguard Worker         }
312*e5436536SAndroid Build Coastguard Worker       } else if (gc->nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) {
313*e5436536SAndroid Build Coastguard Worker         if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) {
314*e5436536SAndroid Build Coastguard Worker           if (NULL ==
315*e5436536SAndroid Build Coastguard Worker               (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal32(ch)))
316*e5436536SAndroid Build Coastguard Worker             goto bail;
317*e5436536SAndroid Build Coastguard Worker         }
318*e5436536SAndroid Build Coastguard Worker         if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) {
319*e5436536SAndroid Build Coastguard Worker           if (NULL ==
320*e5436536SAndroid Build Coastguard Worker               (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag32(ch)))
321*e5436536SAndroid Build Coastguard Worker             goto bail;
322*e5436536SAndroid Build Coastguard Worker         }
323*e5436536SAndroid Build Coastguard Worker       } else {
324*e5436536SAndroid Build Coastguard Worker         if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) {
325*e5436536SAndroid Build Coastguard Worker           if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal(ch)))
326*e5436536SAndroid Build Coastguard Worker             goto bail;
327*e5436536SAndroid Build Coastguard Worker         }
328*e5436536SAndroid Build Coastguard Worker         if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) {
329*e5436536SAndroid Build Coastguard Worker           if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag(ch)))
330*e5436536SAndroid Build Coastguard Worker             goto bail;
331*e5436536SAndroid Build Coastguard Worker         }
332*e5436536SAndroid Build Coastguard Worker       }
333*e5436536SAndroid Build Coastguard Worker     } else {
334*e5436536SAndroid Build Coastguard Worker       qd->QmfDomainIn[ch].hQmfSlotsReal = NULL;
335*e5436536SAndroid Build Coastguard Worker       qd->QmfDomainIn[ch].hQmfSlotsImag = NULL;
336*e5436536SAndroid Build Coastguard Worker     }
337*e5436536SAndroid Build Coastguard Worker 
338*e5436536SAndroid Build Coastguard Worker     size = gc->nQmfOvTimeSlots * gc->nQmfProcBands * CMPLX_MOD;
339*e5436536SAndroid Build Coastguard Worker     if (size > 0) {
340*e5436536SAndroid Build Coastguard Worker       if (gc->nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_16) {
341*e5436536SAndroid Build Coastguard Worker         if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) {
342*e5436536SAndroid Build Coastguard Worker           if (NULL ==
343*e5436536SAndroid Build Coastguard Worker               (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer16(ch)))
344*e5436536SAndroid Build Coastguard Worker             goto bail;
345*e5436536SAndroid Build Coastguard Worker         }
346*e5436536SAndroid Build Coastguard Worker       } else if (gc->nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_32) {
347*e5436536SAndroid Build Coastguard Worker         if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) {
348*e5436536SAndroid Build Coastguard Worker           if (NULL ==
349*e5436536SAndroid Build Coastguard Worker               (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer32(ch)))
350*e5436536SAndroid Build Coastguard Worker             goto bail;
351*e5436536SAndroid Build Coastguard Worker         }
352*e5436536SAndroid Build Coastguard Worker       } else {
353*e5436536SAndroid Build Coastguard Worker         if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) {
354*e5436536SAndroid Build Coastguard Worker           if (NULL ==
355*e5436536SAndroid Build Coastguard Worker               (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer(ch)))
356*e5436536SAndroid Build Coastguard Worker             goto bail;
357*e5436536SAndroid Build Coastguard Worker         }
358*e5436536SAndroid Build Coastguard Worker       }
359*e5436536SAndroid Build Coastguard Worker     } else {
360*e5436536SAndroid Build Coastguard Worker       qd->QmfDomainIn[ch].pOverlapBuffer = NULL;
361*e5436536SAndroid Build Coastguard Worker     }
362*e5436536SAndroid Build Coastguard Worker   }
363*e5436536SAndroid Build Coastguard Worker 
364*e5436536SAndroid Build Coastguard Worker   for (ch = 0; ch < gc->nOutputChannels; ch++) {
365*e5436536SAndroid Build Coastguard Worker     int size = gc->nBandsSynthesis * 9;
366*e5436536SAndroid Build Coastguard Worker     if (size > 0) {
367*e5436536SAndroid Build Coastguard Worker       if (qd->QmfDomainOut[ch].pSynQmfStates == NULL) {
368*e5436536SAndroid Build Coastguard Worker         if (NULL == (qd->QmfDomainOut[ch].pSynQmfStates = GetSynQmfStates(ch)))
369*e5436536SAndroid Build Coastguard Worker           goto bail;
370*e5436536SAndroid Build Coastguard Worker       }
371*e5436536SAndroid Build Coastguard Worker     } else {
372*e5436536SAndroid Build Coastguard Worker       qd->QmfDomainOut[ch].pSynQmfStates = NULL;
373*e5436536SAndroid Build Coastguard Worker     }
374*e5436536SAndroid Build Coastguard Worker   }
375*e5436536SAndroid Build Coastguard Worker 
376*e5436536SAndroid Build Coastguard Worker   return err;
377*e5436536SAndroid Build Coastguard Worker 
378*e5436536SAndroid Build Coastguard Worker bail:
379*e5436536SAndroid Build Coastguard Worker   FDK_QmfDomain_FreePersistentMemory(qd);
380*e5436536SAndroid Build Coastguard Worker   return -1;
381*e5436536SAndroid Build Coastguard Worker }
382*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_ClearPersistentMemory(HANDLE_FDK_QMF_DOMAIN hqd)383*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_ERROR FDK_QmfDomain_ClearPersistentMemory(
384*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_QMF_DOMAIN hqd) {
385*e5436536SAndroid Build Coastguard Worker   QMF_DOMAIN_ERROR err = QMF_DOMAIN_OK;
386*e5436536SAndroid Build Coastguard Worker   int ch, size;
387*e5436536SAndroid Build Coastguard Worker   if (hqd) {
388*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_QMF_DOMAIN_GC gc = &hqd->globalConf;
389*e5436536SAndroid Build Coastguard Worker 
390*e5436536SAndroid Build Coastguard Worker     size = gc->nQmfOvTimeSlots * gc->nQmfProcBands * CMPLX_MOD;
391*e5436536SAndroid Build Coastguard Worker     for (ch = 0; ch < gc->nInputChannels; ch++) {
392*e5436536SAndroid Build Coastguard Worker       if (hqd->QmfDomainIn[ch].pOverlapBuffer) {
393*e5436536SAndroid Build Coastguard Worker         FDKmemclear(hqd->QmfDomainIn[ch].pOverlapBuffer,
394*e5436536SAndroid Build Coastguard Worker                     size * sizeof(FIXP_DBL));
395*e5436536SAndroid Build Coastguard Worker       }
396*e5436536SAndroid Build Coastguard Worker     }
397*e5436536SAndroid Build Coastguard Worker     if (FDK_QmfDomain_InitFilterBank(hqd, 0)) {
398*e5436536SAndroid Build Coastguard Worker       err = QMF_DOMAIN_INIT_ERROR;
399*e5436536SAndroid Build Coastguard Worker     }
400*e5436536SAndroid Build Coastguard Worker   } else {
401*e5436536SAndroid Build Coastguard Worker     err = QMF_DOMAIN_INIT_ERROR;
402*e5436536SAndroid Build Coastguard Worker   }
403*e5436536SAndroid Build Coastguard Worker   return err;
404*e5436536SAndroid Build Coastguard Worker }
405*e5436536SAndroid Build Coastguard Worker 
406*e5436536SAndroid Build Coastguard Worker /*
407*e5436536SAndroid Build Coastguard Worker    FDK_getWorkBuffer
408*e5436536SAndroid Build Coastguard Worker 
409*e5436536SAndroid Build Coastguard Worker     Parameters:
410*e5436536SAndroid Build Coastguard Worker 
411*e5436536SAndroid Build Coastguard Worker     pWorkBuffer        i: array of pointers which point to different workbuffer
412*e5436536SAndroid Build Coastguard Worker    sections workBufferOffset   i: offset in the workbuffer to the requested
413*e5436536SAndroid Build Coastguard Worker    memory memSize            i: size of requested memory
414*e5436536SAndroid Build Coastguard Worker 
415*e5436536SAndroid Build Coastguard Worker     Function:
416*e5436536SAndroid Build Coastguard Worker 
417*e5436536SAndroid Build Coastguard Worker     The functions returns the address to the requested memory in the workbuffer.
418*e5436536SAndroid Build Coastguard Worker 
419*e5436536SAndroid Build Coastguard Worker     The overall workbuffer is divided into several sections. There are
420*e5436536SAndroid Build Coastguard Worker    QMF_MAX_WB_SECTIONS sections of size QMF_WB_SECTION_SIZE. The function
421*e5436536SAndroid Build Coastguard Worker    selects the workbuffer section with the help of the workBufferOffset and than
422*e5436536SAndroid Build Coastguard Worker    it verifies whether the requested amount of memory fits into the selected
423*e5436536SAndroid Build Coastguard Worker    workbuffer section.
424*e5436536SAndroid Build Coastguard Worker 
425*e5436536SAndroid Build Coastguard Worker     Returns:
426*e5436536SAndroid Build Coastguard Worker 
427*e5436536SAndroid Build Coastguard Worker     address to workbuffer
428*e5436536SAndroid Build Coastguard Worker */
FDK_getWorkBuffer(FIXP_DBL ** pWorkBuffer,USHORT workBufferOffset,USHORT workBufferSectSize,USHORT memSize)429*e5436536SAndroid Build Coastguard Worker static FIXP_DBL *FDK_getWorkBuffer(FIXP_DBL **pWorkBuffer,
430*e5436536SAndroid Build Coastguard Worker                                    USHORT workBufferOffset,
431*e5436536SAndroid Build Coastguard Worker                                    USHORT workBufferSectSize, USHORT memSize) {
432*e5436536SAndroid Build Coastguard Worker   int idx1;
433*e5436536SAndroid Build Coastguard Worker   int idx2;
434*e5436536SAndroid Build Coastguard Worker   FIXP_DBL *pwb;
435*e5436536SAndroid Build Coastguard Worker 
436*e5436536SAndroid Build Coastguard Worker   /* a section must be a multiple of the number of processing bands (currently
437*e5436536SAndroid Build Coastguard Worker    * always 64) */
438*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT((workBufferSectSize % 64) == 0);
439*e5436536SAndroid Build Coastguard Worker 
440*e5436536SAndroid Build Coastguard Worker   /* calculate offset within the section */
441*e5436536SAndroid Build Coastguard Worker   idx2 = workBufferOffset % workBufferSectSize;
442*e5436536SAndroid Build Coastguard Worker   /* calculate section number */
443*e5436536SAndroid Build Coastguard Worker   idx1 = (workBufferOffset - idx2) / workBufferSectSize;
444*e5436536SAndroid Build Coastguard Worker   /* maximum sectionnumber is QMF_MAX_WB_SECTIONS */
445*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(idx1 < QMF_MAX_WB_SECTIONS);
446*e5436536SAndroid Build Coastguard Worker 
447*e5436536SAndroid Build Coastguard Worker   /* check, whether workbuffer is available  */
448*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(pWorkBuffer[idx1] != NULL);
449*e5436536SAndroid Build Coastguard Worker 
450*e5436536SAndroid Build Coastguard Worker   /* check, whether buffer fits into selected section */
451*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT((idx2 + memSize) <= workBufferSectSize);
452*e5436536SAndroid Build Coastguard Worker 
453*e5436536SAndroid Build Coastguard Worker   /* get requested address to workbuffer */
454*e5436536SAndroid Build Coastguard Worker   pwb = &pWorkBuffer[idx1][idx2];
455*e5436536SAndroid Build Coastguard Worker 
456*e5436536SAndroid Build Coastguard Worker   return pwb;
457*e5436536SAndroid Build Coastguard Worker }
458*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_FeedWorkBuffer(HANDLE_FDK_QMF_DOMAIN qd,int ch,FIXP_DBL ** pWorkBuffer,USHORT workBufferOffset,USHORT workBufferSectSize,int size)459*e5436536SAndroid Build Coastguard Worker static int FDK_QmfDomain_FeedWorkBuffer(HANDLE_FDK_QMF_DOMAIN qd, int ch,
460*e5436536SAndroid Build Coastguard Worker                                         FIXP_DBL **pWorkBuffer,
461*e5436536SAndroid Build Coastguard Worker                                         USHORT workBufferOffset,
462*e5436536SAndroid Build Coastguard Worker                                         USHORT workBufferSectSize, int size) {
463*e5436536SAndroid Build Coastguard Worker   int err = 0;
464*e5436536SAndroid Build Coastguard Worker   int mem_needed;
465*e5436536SAndroid Build Coastguard Worker 
466*e5436536SAndroid Build Coastguard Worker   mem_needed = qd->QmfDomainIn[ch].workBuf_nBands *
467*e5436536SAndroid Build Coastguard Worker                qd->QmfDomainIn[ch].workBuf_nTimeSlots * CMPLX_MOD;
468*e5436536SAndroid Build Coastguard Worker   if (mem_needed > size) {
469*e5436536SAndroid Build Coastguard Worker     return (err = 1);
470*e5436536SAndroid Build Coastguard Worker   }
471*e5436536SAndroid Build Coastguard Worker   qd->QmfDomainIn[ch].pWorkBuffer = pWorkBuffer;
472*e5436536SAndroid Build Coastguard Worker   qd->QmfDomainIn[ch].workBufferOffset = workBufferOffset;
473*e5436536SAndroid Build Coastguard Worker   qd->QmfDomainIn[ch].workBufferSectSize = workBufferSectSize;
474*e5436536SAndroid Build Coastguard Worker 
475*e5436536SAndroid Build Coastguard Worker   return err;
476*e5436536SAndroid Build Coastguard Worker }
477*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_IsInitialized(const HANDLE_FDK_QMF_DOMAIN qd)478*e5436536SAndroid Build Coastguard Worker int FDK_QmfDomain_IsInitialized(const HANDLE_FDK_QMF_DOMAIN qd) {
479*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(qd != NULL);
480*e5436536SAndroid Build Coastguard Worker   return ((qd->QmfDomainIn[0].pAnaQmfStates == NULL) &&
481*e5436536SAndroid Build Coastguard Worker           (qd->QmfDomainOut[0].pSynQmfStates == NULL))
482*e5436536SAndroid Build Coastguard Worker              ? 0
483*e5436536SAndroid Build Coastguard Worker              : 1;
484*e5436536SAndroid Build Coastguard Worker }
485*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_InitFilterBank(HANDLE_FDK_QMF_DOMAIN qd,UINT extra_flags)486*e5436536SAndroid Build Coastguard Worker int FDK_QmfDomain_InitFilterBank(HANDLE_FDK_QMF_DOMAIN qd, UINT extra_flags) {
487*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(qd != NULL);
488*e5436536SAndroid Build Coastguard Worker   int err = 0;
489*e5436536SAndroid Build Coastguard Worker   int ch, ts;
490*e5436536SAndroid Build Coastguard Worker   HANDLE_FDK_QMF_DOMAIN_GC gc = &qd->globalConf;
491*e5436536SAndroid Build Coastguard Worker   int noCols = gc->nQmfTimeSlots;
492*e5436536SAndroid Build Coastguard Worker   int lsb = gc->nBandsAnalysis;
493*e5436536SAndroid Build Coastguard Worker   int usb = fMin((INT)gc->nBandsSynthesis, 64);
494*e5436536SAndroid Build Coastguard Worker   int nProcBands = gc->nQmfProcBands;
495*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(nProcBands % ALIGNMENT_DEFAULT == 0);
496*e5436536SAndroid Build Coastguard Worker 
497*e5436536SAndroid Build Coastguard Worker   if (extra_flags & QMF_FLAG_MPSLDFB) {
498*e5436536SAndroid Build Coastguard Worker     gc->flags &= ~QMF_FLAG_CLDFB;
499*e5436536SAndroid Build Coastguard Worker     gc->flags |= QMF_FLAG_MPSLDFB;
500*e5436536SAndroid Build Coastguard Worker   }
501*e5436536SAndroid Build Coastguard Worker   for (ch = 0; ch < gc->nInputChannels; ch++) {
502*e5436536SAndroid Build Coastguard Worker     /* distribute memory to slots array */
503*e5436536SAndroid Build Coastguard Worker     FIXP_DBL *ptrOv =
504*e5436536SAndroid Build Coastguard Worker         qd->QmfDomainIn[ch].pOverlapBuffer; /* persistent memory for overlap */
505*e5436536SAndroid Build Coastguard Worker     if ((ptrOv == NULL) && (gc->nQmfOvTimeSlots != 0)) {
506*e5436536SAndroid Build Coastguard Worker       err = 1;
507*e5436536SAndroid Build Coastguard Worker       return err;
508*e5436536SAndroid Build Coastguard Worker     }
509*e5436536SAndroid Build Coastguard Worker     /* This assumes the workbuffer defined for ch0 is the big one being used to
510*e5436536SAndroid Build Coastguard Worker      * hold one full frame of QMF data. */
511*e5436536SAndroid Build Coastguard Worker     FIXP_DBL **ptr =
512*e5436536SAndroid Build Coastguard Worker         qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
513*e5436536SAndroid Build Coastguard Worker             .pWorkBuffer; /* non-persistent workbuffer */
514*e5436536SAndroid Build Coastguard Worker     USHORT workBufferOffset =
515*e5436536SAndroid Build Coastguard Worker         qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
516*e5436536SAndroid Build Coastguard Worker             .workBufferOffset;
517*e5436536SAndroid Build Coastguard Worker     USHORT workBufferSectSize =
518*e5436536SAndroid Build Coastguard Worker         qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
519*e5436536SAndroid Build Coastguard Worker             .workBufferSectSize;
520*e5436536SAndroid Build Coastguard Worker 
521*e5436536SAndroid Build Coastguard Worker     if ((ptr == NULL) && (gc->nQmfTimeSlots != 0)) {
522*e5436536SAndroid Build Coastguard Worker       err = 1;
523*e5436536SAndroid Build Coastguard Worker       return err;
524*e5436536SAndroid Build Coastguard Worker     }
525*e5436536SAndroid Build Coastguard Worker 
526*e5436536SAndroid Build Coastguard Worker     qd->QmfDomainIn[ch].pGlobalConf = gc;
527*e5436536SAndroid Build Coastguard Worker     for (ts = 0; ts < gc->nQmfOvTimeSlots; ts++) {
528*e5436536SAndroid Build Coastguard Worker       qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = ptrOv;
529*e5436536SAndroid Build Coastguard Worker       ptrOv += nProcBands;
530*e5436536SAndroid Build Coastguard Worker       qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = ptrOv;
531*e5436536SAndroid Build Coastguard Worker       ptrOv += nProcBands;
532*e5436536SAndroid Build Coastguard Worker     }
533*e5436536SAndroid Build Coastguard Worker     for (; ts < (gc->nQmfOvTimeSlots + gc->nQmfTimeSlots); ts++) {
534*e5436536SAndroid Build Coastguard Worker       qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = FDK_getWorkBuffer(
535*e5436536SAndroid Build Coastguard Worker           ptr, workBufferOffset, workBufferSectSize, nProcBands);
536*e5436536SAndroid Build Coastguard Worker       workBufferOffset += nProcBands;
537*e5436536SAndroid Build Coastguard Worker       qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = FDK_getWorkBuffer(
538*e5436536SAndroid Build Coastguard Worker           ptr, workBufferOffset, workBufferSectSize, nProcBands);
539*e5436536SAndroid Build Coastguard Worker       workBufferOffset += nProcBands;
540*e5436536SAndroid Build Coastguard Worker     }
541*e5436536SAndroid Build Coastguard Worker     err |= qmfInitAnalysisFilterBank(
542*e5436536SAndroid Build Coastguard Worker         &qd->QmfDomainIn[ch].fb, qd->QmfDomainIn[ch].pAnaQmfStates, noCols,
543*e5436536SAndroid Build Coastguard Worker         (qd->QmfDomainIn[ch].fb.lsb == 0) ? lsb : qd->QmfDomainIn[ch].fb.lsb,
544*e5436536SAndroid Build Coastguard Worker         (qd->QmfDomainIn[ch].fb.usb == 0) ? usb : qd->QmfDomainIn[ch].fb.usb,
545*e5436536SAndroid Build Coastguard Worker         gc->nBandsAnalysis, gc->flags | extra_flags);
546*e5436536SAndroid Build Coastguard Worker   }
547*e5436536SAndroid Build Coastguard Worker 
548*e5436536SAndroid Build Coastguard Worker   for (ch = 0; ch < gc->nOutputChannels; ch++) {
549*e5436536SAndroid Build Coastguard Worker     FIXP_DBL outGain_m = qd->QmfDomainOut[ch].fb.outGain_m;
550*e5436536SAndroid Build Coastguard Worker     int outGain_e = qd->QmfDomainOut[ch].fb.outGain_e;
551*e5436536SAndroid Build Coastguard Worker     int outScale = qmfGetOutScalefactor(&qd->QmfDomainOut[ch].fb);
552*e5436536SAndroid Build Coastguard Worker     err |= qmfInitSynthesisFilterBank(
553*e5436536SAndroid Build Coastguard Worker         &qd->QmfDomainOut[ch].fb, qd->QmfDomainOut[ch].pSynQmfStates, noCols,
554*e5436536SAndroid Build Coastguard Worker         (qd->QmfDomainOut[ch].fb.lsb == 0) ? lsb : qd->QmfDomainOut[ch].fb.lsb,
555*e5436536SAndroid Build Coastguard Worker         (qd->QmfDomainOut[ch].fb.usb == 0) ? usb : qd->QmfDomainOut[ch].fb.usb,
556*e5436536SAndroid Build Coastguard Worker         gc->nBandsSynthesis, gc->flags | extra_flags);
557*e5436536SAndroid Build Coastguard Worker     if (outGain_m != (FIXP_DBL)0) {
558*e5436536SAndroid Build Coastguard Worker       qmfChangeOutGain(&qd->QmfDomainOut[ch].fb, outGain_m, outGain_e);
559*e5436536SAndroid Build Coastguard Worker     }
560*e5436536SAndroid Build Coastguard Worker     if (outScale) {
561*e5436536SAndroid Build Coastguard Worker       qmfChangeOutScalefactor(&qd->QmfDomainOut[ch].fb, outScale);
562*e5436536SAndroid Build Coastguard Worker     }
563*e5436536SAndroid Build Coastguard Worker   }
564*e5436536SAndroid Build Coastguard Worker 
565*e5436536SAndroid Build Coastguard Worker   return err;
566*e5436536SAndroid Build Coastguard Worker }
567*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_SaveOverlap(HANDLE_FDK_QMF_DOMAIN_IN qd_ch,int offset)568*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_SaveOverlap(HANDLE_FDK_QMF_DOMAIN_IN qd_ch, int offset) {
569*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(qd_ch != NULL);
570*e5436536SAndroid Build Coastguard Worker   int ts;
571*e5436536SAndroid Build Coastguard Worker   HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
572*e5436536SAndroid Build Coastguard Worker   int ovSlots = gc->nQmfOvTimeSlots;
573*e5436536SAndroid Build Coastguard Worker   int nCols = gc->nQmfTimeSlots;
574*e5436536SAndroid Build Coastguard Worker   int nProcBands = gc->nQmfProcBands;
575*e5436536SAndroid Build Coastguard Worker   FIXP_DBL **qmfReal = qd_ch->hQmfSlotsReal;
576*e5436536SAndroid Build Coastguard Worker   FIXP_DBL **qmfImag = qd_ch->hQmfSlotsImag;
577*e5436536SAndroid Build Coastguard Worker   QMF_SCALE_FACTOR *pScaling = &qd_ch->scaling;
578*e5436536SAndroid Build Coastguard Worker 
579*e5436536SAndroid Build Coastguard Worker   /* for high part it would be enough to save only used part of overlap area */
580*e5436536SAndroid Build Coastguard Worker   if (qmfImag != NULL) {
581*e5436536SAndroid Build Coastguard Worker     for (ts = offset; ts < ovSlots; ts++) {
582*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(qmfReal[ts], qmfReal[nCols + ts],
583*e5436536SAndroid Build Coastguard Worker                 sizeof(FIXP_DBL) * nProcBands);
584*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(qmfImag[ts], qmfImag[nCols + ts],
585*e5436536SAndroid Build Coastguard Worker                 sizeof(FIXP_DBL) * nProcBands);
586*e5436536SAndroid Build Coastguard Worker     }
587*e5436536SAndroid Build Coastguard Worker   } else {
588*e5436536SAndroid Build Coastguard Worker     for (ts = 0; ts < ovSlots; ts++) {
589*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(qmfReal[ts], qmfReal[nCols + ts],
590*e5436536SAndroid Build Coastguard Worker                 sizeof(FIXP_DBL) * nProcBands);
591*e5436536SAndroid Build Coastguard Worker     }
592*e5436536SAndroid Build Coastguard Worker   }
593*e5436536SAndroid Build Coastguard Worker   pScaling->ov_lb_scale = pScaling->lb_scale;
594*e5436536SAndroid Build Coastguard Worker }
595*e5436536SAndroid Build Coastguard Worker 
596*e5436536SAndroid Build Coastguard Worker   /* Convert headroom bits to exponent */
597*e5436536SAndroid Build Coastguard Worker #define SCALE2EXP(s) (15 - (s))
598*e5436536SAndroid Build Coastguard Worker #define EXP2SCALE(e) (15 - (e))
599*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch,const int ts,const int start_band,const int stop_band,FIXP_DBL * pQmfOutReal,FIXP_DBL * pQmfOutImag,const int exp_out)600*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts,
601*e5436536SAndroid Build Coastguard Worker                            const int start_band, const int stop_band,
602*e5436536SAndroid Build Coastguard Worker                            FIXP_DBL *pQmfOutReal, FIXP_DBL *pQmfOutImag,
603*e5436536SAndroid Build Coastguard Worker                            const int exp_out) {
604*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(qd_ch != NULL);
605*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(pQmfOutReal != NULL);
606*e5436536SAndroid Build Coastguard Worker   HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
607*e5436536SAndroid Build Coastguard Worker   const FIXP_DBL *real = qd_ch->hQmfSlotsReal[ts];
608*e5436536SAndroid Build Coastguard Worker   const FIXP_DBL *imag = qd_ch->hQmfSlotsImag[ts];
609*e5436536SAndroid Build Coastguard Worker   const int ovSlots = gc->nQmfOvTimeSlots;
610*e5436536SAndroid Build Coastguard Worker   const int exp_lb = SCALE2EXP((ts < ovSlots) ? qd_ch->scaling.ov_lb_scale
611*e5436536SAndroid Build Coastguard Worker                                               : qd_ch->scaling.lb_scale);
612*e5436536SAndroid Build Coastguard Worker   const int exp_hb = SCALE2EXP(qd_ch->scaling.hb_scale);
613*e5436536SAndroid Build Coastguard Worker   const int lsb = qd_ch->fb.lsb;
614*e5436536SAndroid Build Coastguard Worker   const int usb = qd_ch->fb.usb;
615*e5436536SAndroid Build Coastguard Worker   int b = start_band;
616*e5436536SAndroid Build Coastguard Worker   int lb_sf, hb_sf;
617*e5436536SAndroid Build Coastguard Worker 
618*e5436536SAndroid Build Coastguard Worker   int target_exp =
619*e5436536SAndroid Build Coastguard Worker       ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + qd_ch->fb.filterScale;
620*e5436536SAndroid Build Coastguard Worker 
621*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(ts < (gc->nQmfTimeSlots + gc->nQmfOvTimeSlots));
622*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(start_band >= 0);
623*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(stop_band <= gc->nQmfProcBands);
624*e5436536SAndroid Build Coastguard Worker 
625*e5436536SAndroid Build Coastguard Worker   if (qd_ch->fb.no_channels == 24) {
626*e5436536SAndroid Build Coastguard Worker     target_exp -= 1;
627*e5436536SAndroid Build Coastguard Worker   }
628*e5436536SAndroid Build Coastguard Worker 
629*e5436536SAndroid Build Coastguard Worker   /* Limit scaling factors to maximum negative value to avoid faulty behaviour
630*e5436536SAndroid Build Coastguard Worker      due to right-shifts. Corresponding asserts were observed during robustness
631*e5436536SAndroid Build Coastguard Worker      testing.
632*e5436536SAndroid Build Coastguard Worker    */
633*e5436536SAndroid Build Coastguard Worker   lb_sf = fMax(exp_lb - target_exp - exp_out, -31);
634*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(lb_sf < 32);
635*e5436536SAndroid Build Coastguard Worker   hb_sf = fMax(exp_hb - target_exp - exp_out, -31);
636*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(hb_sf < 32);
637*e5436536SAndroid Build Coastguard Worker 
638*e5436536SAndroid Build Coastguard Worker   if (pQmfOutImag == NULL) {
639*e5436536SAndroid Build Coastguard Worker     for (; b < fMin(lsb, stop_band); b++) {
640*e5436536SAndroid Build Coastguard Worker       pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf);
641*e5436536SAndroid Build Coastguard Worker     }
642*e5436536SAndroid Build Coastguard Worker     for (; b < fMin(usb, stop_band); b++) {
643*e5436536SAndroid Build Coastguard Worker       pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf);
644*e5436536SAndroid Build Coastguard Worker     }
645*e5436536SAndroid Build Coastguard Worker     for (; b < stop_band; b++) {
646*e5436536SAndroid Build Coastguard Worker       pQmfOutReal[b] = (FIXP_DBL)0;
647*e5436536SAndroid Build Coastguard Worker     }
648*e5436536SAndroid Build Coastguard Worker   } else {
649*e5436536SAndroid Build Coastguard Worker     FDK_ASSERT(imag != NULL);
650*e5436536SAndroid Build Coastguard Worker     for (; b < fMin(lsb, stop_band); b++) {
651*e5436536SAndroid Build Coastguard Worker       pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf);
652*e5436536SAndroid Build Coastguard Worker       pQmfOutImag[b] = scaleValueSaturate(imag[b], lb_sf);
653*e5436536SAndroid Build Coastguard Worker     }
654*e5436536SAndroid Build Coastguard Worker     for (; b < fMin(usb, stop_band); b++) {
655*e5436536SAndroid Build Coastguard Worker       pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf);
656*e5436536SAndroid Build Coastguard Worker       pQmfOutImag[b] = scaleValueSaturate(imag[b], hb_sf);
657*e5436536SAndroid Build Coastguard Worker     }
658*e5436536SAndroid Build Coastguard Worker     for (; b < stop_band; b++) {
659*e5436536SAndroid Build Coastguard Worker       pQmfOutReal[b] = (FIXP_DBL)0;
660*e5436536SAndroid Build Coastguard Worker       pQmfOutImag[b] = (FIXP_DBL)0;
661*e5436536SAndroid Build Coastguard Worker     }
662*e5436536SAndroid Build Coastguard Worker   }
663*e5436536SAndroid Build Coastguard Worker }
664*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_GetWorkBuffer(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch,const int ts,FIXP_DBL ** ppQmfReal,FIXP_DBL ** ppQmfImag)665*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_GetWorkBuffer(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch,
666*e5436536SAndroid Build Coastguard Worker                                  const int ts, FIXP_DBL **ppQmfReal,
667*e5436536SAndroid Build Coastguard Worker                                  FIXP_DBL **ppQmfImag) {
668*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(qd_ch != NULL);
669*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(ppQmfReal != NULL);
670*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(ppQmfImag != NULL);
671*e5436536SAndroid Build Coastguard Worker   const int bands = qd_ch->workBuf_nBands;
672*e5436536SAndroid Build Coastguard Worker   FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
673*e5436536SAndroid Build Coastguard Worker   USHORT workBufferOffset = qd_ch->workBufferOffset;
674*e5436536SAndroid Build Coastguard Worker   USHORT workBufferSectSize = qd_ch->workBufferSectSize;
675*e5436536SAndroid Build Coastguard Worker 
676*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(bands > 0);
677*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(ts < qd_ch->workBuf_nTimeSlots);
678*e5436536SAndroid Build Coastguard Worker 
679*e5436536SAndroid Build Coastguard Worker   *ppQmfReal = FDK_getWorkBuffer(
680*e5436536SAndroid Build Coastguard Worker       pWorkBuf, workBufferOffset + (ts * CMPLX_MOD + 0) * bands,
681*e5436536SAndroid Build Coastguard Worker       workBufferSectSize, bands);
682*e5436536SAndroid Build Coastguard Worker   *ppQmfImag = FDK_getWorkBuffer(
683*e5436536SAndroid Build Coastguard Worker       pWorkBuf, workBufferOffset + (ts * CMPLX_MOD + 1) * bands,
684*e5436536SAndroid Build Coastguard Worker       workBufferSectSize, bands);
685*e5436536SAndroid Build Coastguard Worker }
686*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_WorkBuffer2ProcChannel(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch)687*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_WorkBuffer2ProcChannel(
688*e5436536SAndroid Build Coastguard Worker     const HANDLE_FDK_QMF_DOMAIN_IN qd_ch) {
689*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(qd_ch != NULL);
690*e5436536SAndroid Build Coastguard Worker   HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
691*e5436536SAndroid Build Coastguard Worker   FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
692*e5436536SAndroid Build Coastguard Worker   USHORT workBufferOffset = qd_ch->workBufferOffset;
693*e5436536SAndroid Build Coastguard Worker   USHORT workBufferSectSize = qd_ch->workBufferSectSize;
694*e5436536SAndroid Build Coastguard Worker 
695*e5436536SAndroid Build Coastguard Worker   if (FDK_getWorkBuffer(pWorkBuf, workBufferOffset, workBufferSectSize,
696*e5436536SAndroid Build Coastguard Worker                         qd_ch->workBuf_nBands) ==
697*e5436536SAndroid Build Coastguard Worker       qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots]) {
698*e5436536SAndroid Build Coastguard Worker     /* work buffer is part of processing channel => nothing to do */
699*e5436536SAndroid Build Coastguard Worker     return;
700*e5436536SAndroid Build Coastguard Worker   } else {
701*e5436536SAndroid Build Coastguard Worker     /* copy parked new QMF data to processing channel */
702*e5436536SAndroid Build Coastguard Worker     const int bands = qd_ch->workBuf_nBands;
703*e5436536SAndroid Build Coastguard Worker     const int slots = qd_ch->workBuf_nTimeSlots;
704*e5436536SAndroid Build Coastguard Worker     int ts;
705*e5436536SAndroid Build Coastguard Worker     for (ts = 0; ts < slots; ts++) {
706*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts],
707*e5436536SAndroid Build Coastguard Worker                 FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
708*e5436536SAndroid Build Coastguard Worker                                   workBufferSectSize, bands),
709*e5436536SAndroid Build Coastguard Worker                 sizeof(FIXP_DBL) * bands);  // parkBuf_to_anaMatrix
710*e5436536SAndroid Build Coastguard Worker       workBufferOffset += bands;
711*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts],
712*e5436536SAndroid Build Coastguard Worker                 FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
713*e5436536SAndroid Build Coastguard Worker                                   workBufferSectSize, bands),
714*e5436536SAndroid Build Coastguard Worker                 sizeof(FIXP_DBL) * bands);
715*e5436536SAndroid Build Coastguard Worker       workBufferOffset += bands;
716*e5436536SAndroid Build Coastguard Worker     }
717*e5436536SAndroid Build Coastguard Worker   }
718*e5436536SAndroid Build Coastguard Worker }
719*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_QmfData2HBE(HANDLE_FDK_QMF_DOMAIN_IN qd_ch,FIXP_DBL ** ppQmfReal,FIXP_DBL ** ppQmfImag)720*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_QmfData2HBE(HANDLE_FDK_QMF_DOMAIN_IN qd_ch,
721*e5436536SAndroid Build Coastguard Worker                                FIXP_DBL **ppQmfReal, FIXP_DBL **ppQmfImag) {
722*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(qd_ch != NULL);
723*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(ppQmfReal != NULL);
724*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(ppQmfImag != NULL);
725*e5436536SAndroid Build Coastguard Worker   HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
726*e5436536SAndroid Build Coastguard Worker   FIXP_DBL **pWorkBuf = qd_ch->pWorkBuffer;
727*e5436536SAndroid Build Coastguard Worker   USHORT workBufferOffset = qd_ch->workBufferOffset;
728*e5436536SAndroid Build Coastguard Worker   USHORT workBufferSectSize = qd_ch->workBufferSectSize;
729*e5436536SAndroid Build Coastguard Worker 
730*e5436536SAndroid Build Coastguard Worker   if (FDK_getWorkBuffer(pWorkBuf, workBufferOffset, workBufferSectSize,
731*e5436536SAndroid Build Coastguard Worker                         qd_ch->workBuf_nBands) ==
732*e5436536SAndroid Build Coastguard Worker       qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots]) {  // left channel (anaMatrix)
733*e5436536SAndroid Build Coastguard Worker     int ts;
734*e5436536SAndroid Build Coastguard Worker     const int bands = gc->nBandsAnalysis;
735*e5436536SAndroid Build Coastguard Worker     const int slots = qd_ch->workBuf_nTimeSlots;
736*e5436536SAndroid Build Coastguard Worker     FDK_ASSERT(bands <= 64);
737*e5436536SAndroid Build Coastguard Worker     for (ts = 0; ts < slots; ts++) {
738*e5436536SAndroid Build Coastguard Worker       /* copy current data of processing channel */
739*e5436536SAndroid Build Coastguard Worker       FIXP_DBL tmp[64];  // one slot
740*e5436536SAndroid Build Coastguard Worker       /* real */
741*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(tmp, qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts],
742*e5436536SAndroid Build Coastguard Worker                 sizeof(FIXP_DBL) * bands);  // anaMatrix_to_tmp
743*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts], ppQmfReal[ts],
744*e5436536SAndroid Build Coastguard Worker                 sizeof(FIXP_DBL) * bands);  // HBE_to_anaMatrix
745*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(ppQmfReal[ts], tmp, sizeof(FIXP_DBL) * bands);  // tmp_to_HBE
746*e5436536SAndroid Build Coastguard Worker       /* imag */
747*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(tmp, qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts],
748*e5436536SAndroid Build Coastguard Worker                 sizeof(FIXP_DBL) * bands);
749*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts], ppQmfImag[ts],
750*e5436536SAndroid Build Coastguard Worker                 sizeof(FIXP_DBL) * bands);
751*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(ppQmfImag[ts], tmp, sizeof(FIXP_DBL) * bands);
752*e5436536SAndroid Build Coastguard Worker     }
753*e5436536SAndroid Build Coastguard Worker   } else {  // right channel (parkBuf)
754*e5436536SAndroid Build Coastguard Worker     const int bands = qd_ch->workBuf_nBands;
755*e5436536SAndroid Build Coastguard Worker     const int slots = qd_ch->workBuf_nTimeSlots;
756*e5436536SAndroid Build Coastguard Worker     int ts;
757*e5436536SAndroid Build Coastguard Worker     FDK_ASSERT(qd_ch->workBuf_nBands == gc->nBandsAnalysis);
758*e5436536SAndroid Build Coastguard Worker     for (ts = 0; ts < slots; ts++) {
759*e5436536SAndroid Build Coastguard Worker       /* copy HBE QMF data buffer to processing channel */
760*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(qd_ch->hQmfSlotsReal[gc->nQmfOvTimeSlots + ts], ppQmfReal[ts],
761*e5436536SAndroid Build Coastguard Worker                 sizeof(FIXP_DBL) * bands);  // HBE_to_anaMatrix
762*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(qd_ch->hQmfSlotsImag[gc->nQmfOvTimeSlots + ts], ppQmfImag[ts],
763*e5436536SAndroid Build Coastguard Worker                 sizeof(FIXP_DBL) * bands);
764*e5436536SAndroid Build Coastguard Worker       /* copy parked new QMF data to HBE QMF data buffer */
765*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(ppQmfReal[ts],
766*e5436536SAndroid Build Coastguard Worker                 FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
767*e5436536SAndroid Build Coastguard Worker                                   workBufferSectSize, bands),
768*e5436536SAndroid Build Coastguard Worker                 sizeof(FIXP_DBL) * bands);  // parkBuf_to_HBE
769*e5436536SAndroid Build Coastguard Worker       workBufferOffset += bands;
770*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(ppQmfImag[ts],
771*e5436536SAndroid Build Coastguard Worker                 FDK_getWorkBuffer(pWorkBuf, workBufferOffset,
772*e5436536SAndroid Build Coastguard Worker                                   workBufferSectSize, bands),
773*e5436536SAndroid Build Coastguard Worker                 sizeof(FIXP_DBL) * bands);
774*e5436536SAndroid Build Coastguard Worker       workBufferOffset += bands;
775*e5436536SAndroid Build Coastguard Worker     }
776*e5436536SAndroid Build Coastguard Worker   }
777*e5436536SAndroid Build Coastguard Worker }
778*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_ClearRequested(HANDLE_FDK_QMF_DOMAIN_GC hgc)779*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_ClearRequested(HANDLE_FDK_QMF_DOMAIN_GC hgc) {
780*e5436536SAndroid Build Coastguard Worker   hgc->qmfDomainExplicitConfig = 0;
781*e5436536SAndroid Build Coastguard Worker   hgc->flags_requested = 0;
782*e5436536SAndroid Build Coastguard Worker   hgc->nInputChannels_requested = 0;
783*e5436536SAndroid Build Coastguard Worker   hgc->nOutputChannels_requested = 0;
784*e5436536SAndroid Build Coastguard Worker   hgc->parkChannel_requested = 0;
785*e5436536SAndroid Build Coastguard Worker   hgc->nBandsAnalysis_requested = 0;
786*e5436536SAndroid Build Coastguard Worker   hgc->nBandsSynthesis_requested = 0;
787*e5436536SAndroid Build Coastguard Worker   hgc->nQmfTimeSlots_requested = 0;
788*e5436536SAndroid Build Coastguard Worker   hgc->nQmfOvTimeSlots_requested = 0;
789*e5436536SAndroid Build Coastguard Worker   hgc->nQmfProcBands_requested = 0;
790*e5436536SAndroid Build Coastguard Worker   hgc->nQmfProcChannels_requested = 0;
791*e5436536SAndroid Build Coastguard Worker }
792*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_ClearConfigured(HANDLE_FDK_QMF_DOMAIN_GC hgc)793*e5436536SAndroid Build Coastguard Worker static void FDK_QmfDomain_ClearConfigured(HANDLE_FDK_QMF_DOMAIN_GC hgc) {
794*e5436536SAndroid Build Coastguard Worker   hgc->flags = 0;
795*e5436536SAndroid Build Coastguard Worker   hgc->nInputChannels = 0;
796*e5436536SAndroid Build Coastguard Worker   hgc->nOutputChannels = 0;
797*e5436536SAndroid Build Coastguard Worker   hgc->parkChannel = 0;
798*e5436536SAndroid Build Coastguard Worker   hgc->nBandsAnalysis = 0;
799*e5436536SAndroid Build Coastguard Worker   hgc->nBandsSynthesis = 0;
800*e5436536SAndroid Build Coastguard Worker   hgc->nQmfTimeSlots = 0;
801*e5436536SAndroid Build Coastguard Worker   hgc->nQmfOvTimeSlots = 0;
802*e5436536SAndroid Build Coastguard Worker   hgc->nQmfProcBands = 0;
803*e5436536SAndroid Build Coastguard Worker   hgc->nQmfProcChannels = 0;
804*e5436536SAndroid Build Coastguard Worker }
805*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_ClearFilterBank(HANDLE_FDK_QMF_DOMAIN hqd)806*e5436536SAndroid Build Coastguard Worker static void FDK_QmfDomain_ClearFilterBank(HANDLE_FDK_QMF_DOMAIN hqd) {
807*e5436536SAndroid Build Coastguard Worker   int ch;
808*e5436536SAndroid Build Coastguard Worker 
809*e5436536SAndroid Build Coastguard Worker   for (ch = 0; ch < ((8) + (1)); ch++) {
810*e5436536SAndroid Build Coastguard Worker     FDKmemclear(&hqd->QmfDomainIn[ch].fb, sizeof(hqd->QmfDomainIn[ch].fb));
811*e5436536SAndroid Build Coastguard Worker   }
812*e5436536SAndroid Build Coastguard Worker 
813*e5436536SAndroid Build Coastguard Worker   for (ch = 0; ch < ((8) + (1)); ch++) {
814*e5436536SAndroid Build Coastguard Worker     FDKmemclear(&hqd->QmfDomainOut[ch].fb, sizeof(hqd->QmfDomainIn[ch].fb));
815*e5436536SAndroid Build Coastguard Worker   }
816*e5436536SAndroid Build Coastguard Worker }
817*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_Configure(HANDLE_FDK_QMF_DOMAIN hqd)818*e5436536SAndroid Build Coastguard Worker QMF_DOMAIN_ERROR FDK_QmfDomain_Configure(HANDLE_FDK_QMF_DOMAIN hqd) {
819*e5436536SAndroid Build Coastguard Worker   FDK_ASSERT(hqd != NULL);
820*e5436536SAndroid Build Coastguard Worker   QMF_DOMAIN_ERROR err = QMF_DOMAIN_OK;
821*e5436536SAndroid Build Coastguard Worker   int i, size_main, size, size_temp = 0;
822*e5436536SAndroid Build Coastguard Worker 
823*e5436536SAndroid Build Coastguard Worker   HANDLE_FDK_QMF_DOMAIN_GC hgc = &hqd->globalConf;
824*e5436536SAndroid Build Coastguard Worker   FIXP_DBL **pWorkBuffer = hgc->pWorkBuffer;
825*e5436536SAndroid Build Coastguard Worker 
826*e5436536SAndroid Build Coastguard Worker   int hasChanged = 0;
827*e5436536SAndroid Build Coastguard Worker 
828*e5436536SAndroid Build Coastguard Worker   if ((hgc->nQmfProcChannels_requested > 0) &&
829*e5436536SAndroid Build Coastguard Worker       (hgc->nQmfProcBands_requested != 64)) {
830*e5436536SAndroid Build Coastguard Worker     return QMF_DOMAIN_INIT_ERROR;
831*e5436536SAndroid Build Coastguard Worker   }
832*e5436536SAndroid Build Coastguard Worker   if (hgc->nBandsAnalysis_requested > hgc->nQmfProcBands_requested) {
833*e5436536SAndroid Build Coastguard Worker     /* In general the output of the qmf analysis is written to QMF memory slots
834*e5436536SAndroid Build Coastguard Worker        which size is defined by nQmfProcBands. nBandsSynthesis may be larger
835*e5436536SAndroid Build Coastguard Worker        than nQmfProcBands. This is e.g. the case if the QMF based resampler is
836*e5436536SAndroid Build Coastguard Worker        used.
837*e5436536SAndroid Build Coastguard Worker     */
838*e5436536SAndroid Build Coastguard Worker     return QMF_DOMAIN_INIT_ERROR;
839*e5436536SAndroid Build Coastguard Worker   }
840*e5436536SAndroid Build Coastguard Worker 
841*e5436536SAndroid Build Coastguard Worker   /* 1. adjust change of processing channels by comparison of current and
842*e5436536SAndroid Build Coastguard Worker    * requested parameters */
843*e5436536SAndroid Build Coastguard Worker   if ((hgc->nQmfProcChannels != hgc->nQmfProcChannels_requested) ||
844*e5436536SAndroid Build Coastguard Worker       (hgc->nQmfProcBands != hgc->nQmfProcBands_requested) ||
845*e5436536SAndroid Build Coastguard Worker       (hgc->nQmfTimeSlots != hgc->nQmfTimeSlots_requested)) {
846*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < hgc->nQmfProcChannels_requested; i++) {
847*e5436536SAndroid Build Coastguard Worker       hqd->QmfDomainIn[i].workBuf_nBands = hgc->nQmfProcBands_requested;
848*e5436536SAndroid Build Coastguard Worker       hgc->nQmfProcBands = hgc->nQmfProcBands_requested;
849*e5436536SAndroid Build Coastguard Worker 
850*e5436536SAndroid Build Coastguard Worker       hqd->QmfDomainIn[i].workBuf_nTimeSlots = hgc->nQmfTimeSlots_requested;
851*e5436536SAndroid Build Coastguard Worker     }
852*e5436536SAndroid Build Coastguard Worker 
853*e5436536SAndroid Build Coastguard Worker     hgc->nQmfProcChannels =
854*e5436536SAndroid Build Coastguard Worker         hgc->nQmfProcChannels_requested; /* keep highest value encountered so
855*e5436536SAndroid Build Coastguard Worker                                             far as allocated */
856*e5436536SAndroid Build Coastguard Worker 
857*e5436536SAndroid Build Coastguard Worker     hasChanged = 1;
858*e5436536SAndroid Build Coastguard Worker   }
859*e5436536SAndroid Build Coastguard Worker 
860*e5436536SAndroid Build Coastguard Worker   /* 2. reallocate persistent memory if necessary (analysis state-buffers,
861*e5436536SAndroid Build Coastguard Worker    * timeslot-pointer-array, overlap-buffers, synthesis state-buffers) */
862*e5436536SAndroid Build Coastguard Worker   if ((hgc->nInputChannels != hgc->nInputChannels_requested) ||
863*e5436536SAndroid Build Coastguard Worker       (hgc->nBandsAnalysis != hgc->nBandsAnalysis_requested) ||
864*e5436536SAndroid Build Coastguard Worker       (hgc->nQmfTimeSlots != hgc->nQmfTimeSlots_requested) ||
865*e5436536SAndroid Build Coastguard Worker       (hgc->nQmfOvTimeSlots != hgc->nQmfOvTimeSlots_requested) ||
866*e5436536SAndroid Build Coastguard Worker       (hgc->nOutputChannels != hgc->nOutputChannels_requested) ||
867*e5436536SAndroid Build Coastguard Worker       (hgc->nBandsSynthesis != hgc->nBandsSynthesis_requested) ||
868*e5436536SAndroid Build Coastguard Worker       (hgc->parkChannel != hgc->parkChannel_requested)) {
869*e5436536SAndroid Build Coastguard Worker     hgc->nInputChannels = hgc->nInputChannels_requested;
870*e5436536SAndroid Build Coastguard Worker     hgc->nBandsAnalysis = hgc->nBandsAnalysis_requested;
871*e5436536SAndroid Build Coastguard Worker     hgc->nQmfTimeSlots = hgc->nQmfTimeSlots_requested;
872*e5436536SAndroid Build Coastguard Worker     hgc->nQmfOvTimeSlots = hgc->nQmfOvTimeSlots_requested;
873*e5436536SAndroid Build Coastguard Worker     hgc->nOutputChannels = hgc->nOutputChannels_requested;
874*e5436536SAndroid Build Coastguard Worker     hgc->nBandsSynthesis = hgc->nBandsSynthesis_requested;
875*e5436536SAndroid Build Coastguard Worker     hgc->parkChannel = hgc->parkChannel_requested;
876*e5436536SAndroid Build Coastguard Worker 
877*e5436536SAndroid Build Coastguard Worker     if (FDK_QmfDomain_AllocatePersistentMemory(hqd)) {
878*e5436536SAndroid Build Coastguard Worker       err = QMF_DOMAIN_OUT_OF_MEMORY;
879*e5436536SAndroid Build Coastguard Worker       goto bail;
880*e5436536SAndroid Build Coastguard Worker     }
881*e5436536SAndroid Build Coastguard Worker 
882*e5436536SAndroid Build Coastguard Worker     /* 3. set request-flag for downsampled SBR */
883*e5436536SAndroid Build Coastguard Worker     if ((hgc->nBandsAnalysis == 32) && (hgc->nBandsSynthesis == 32) &&
884*e5436536SAndroid Build Coastguard Worker         !(hgc->flags & (QMF_FLAG_CLDFB | QMF_FLAG_MPSLDFB))) {
885*e5436536SAndroid Build Coastguard Worker       hgc->flags_requested |= QMF_FLAG_DOWNSAMPLED;
886*e5436536SAndroid Build Coastguard Worker     }
887*e5436536SAndroid Build Coastguard Worker 
888*e5436536SAndroid Build Coastguard Worker     hasChanged = 1;
889*e5436536SAndroid Build Coastguard Worker   }
890*e5436536SAndroid Build Coastguard Worker 
891*e5436536SAndroid Build Coastguard Worker   /* 4. initialize tables and buffer for QMF-resampler */
892*e5436536SAndroid Build Coastguard Worker 
893*e5436536SAndroid Build Coastguard Worker   /* 5. set requested flags */
894*e5436536SAndroid Build Coastguard Worker   if (hgc->flags != hgc->flags_requested) {
895*e5436536SAndroid Build Coastguard Worker     if ((hgc->flags_requested & QMF_FLAG_MPSLDFB) &&
896*e5436536SAndroid Build Coastguard Worker         (hgc->flags_requested & QMF_FLAG_CLDFB)) {
897*e5436536SAndroid Build Coastguard Worker       hgc->flags_requested &= ~QMF_FLAG_CLDFB;
898*e5436536SAndroid Build Coastguard Worker     }
899*e5436536SAndroid Build Coastguard Worker     hgc->flags = hgc->flags_requested;
900*e5436536SAndroid Build Coastguard Worker     hasChanged = 1;
901*e5436536SAndroid Build Coastguard Worker   }
902*e5436536SAndroid Build Coastguard Worker 
903*e5436536SAndroid Build Coastguard Worker   if (hasChanged) {
904*e5436536SAndroid Build Coastguard Worker     /* 6. recalculate and check size of required workbuffer-space */
905*e5436536SAndroid Build Coastguard Worker 
906*e5436536SAndroid Build Coastguard Worker     if (hgc->parkChannel && (hqd->globalConf.nQmfProcChannels == 1)) {
907*e5436536SAndroid Build Coastguard Worker       /* configure temp QMF buffer for parking right channel MPS212 output,
908*e5436536SAndroid Build Coastguard Worker        * (USAC stereoConfigIndex 3 only) */
909*e5436536SAndroid Build Coastguard Worker       hqd->QmfDomainIn[1].workBuf_nBands = hqd->globalConf.nBandsAnalysis;
910*e5436536SAndroid Build Coastguard Worker       hqd->QmfDomainIn[1].workBuf_nTimeSlots = hqd->globalConf.nQmfTimeSlots;
911*e5436536SAndroid Build Coastguard Worker       size_temp = hqd->QmfDomainIn[1].workBuf_nBands *
912*e5436536SAndroid Build Coastguard Worker                   hqd->QmfDomainIn[1].workBuf_nTimeSlots * CMPLX_MOD;
913*e5436536SAndroid Build Coastguard Worker     }
914*e5436536SAndroid Build Coastguard Worker 
915*e5436536SAndroid Build Coastguard Worker     size_main = hqd->QmfDomainIn[0].workBuf_nBands *
916*e5436536SAndroid Build Coastguard Worker                 hqd->QmfDomainIn[0].workBuf_nTimeSlots * CMPLX_MOD;
917*e5436536SAndroid Build Coastguard Worker 
918*e5436536SAndroid Build Coastguard Worker     size = size_main * hgc->nQmfProcChannels + size_temp;
919*e5436536SAndroid Build Coastguard Worker 
920*e5436536SAndroid Build Coastguard Worker     if (size > (QMF_MAX_WB_SECTIONS * QMF_WB_SECTION_SIZE)) {
921*e5436536SAndroid Build Coastguard Worker       err = QMF_DOMAIN_OUT_OF_MEMORY;
922*e5436536SAndroid Build Coastguard Worker       goto bail;
923*e5436536SAndroid Build Coastguard Worker     }
924*e5436536SAndroid Build Coastguard Worker 
925*e5436536SAndroid Build Coastguard Worker     /* 7. allocate additional workbuffer if necessary */
926*e5436536SAndroid Build Coastguard Worker     if ((size > 0 /* *QMF_WB_SECTION_SIZE */) && (pWorkBuffer[0] == NULL)) {
927*e5436536SAndroid Build Coastguard Worker       /* get work buffer of size QMF_WB_SECTION_SIZE */
928*e5436536SAndroid Build Coastguard Worker       pWorkBuffer[0] = GetQmfWorkBufferCore6();
929*e5436536SAndroid Build Coastguard Worker     }
930*e5436536SAndroid Build Coastguard Worker 
931*e5436536SAndroid Build Coastguard Worker     if ((size > 1 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[1] == NULL)) {
932*e5436536SAndroid Build Coastguard Worker       /* get work buffer of size QMF_WB_SECTION_SIZE */
933*e5436536SAndroid Build Coastguard Worker       pWorkBuffer[1] = GetQmfWorkBufferCore1();
934*e5436536SAndroid Build Coastguard Worker     }
935*e5436536SAndroid Build Coastguard Worker 
936*e5436536SAndroid Build Coastguard Worker     if ((size > 2 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[2] == NULL)) {
937*e5436536SAndroid Build Coastguard Worker       /* get work buffer of size QMF_WB_SECTION_SIZE */
938*e5436536SAndroid Build Coastguard Worker       pWorkBuffer[2] = GetQmfWorkBufferCore3();
939*e5436536SAndroid Build Coastguard Worker     }
940*e5436536SAndroid Build Coastguard Worker 
941*e5436536SAndroid Build Coastguard Worker     if ((size > 3 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[3] == NULL)) {
942*e5436536SAndroid Build Coastguard Worker       /* get work buffer of size QMF_WB_SECTION_SIZE */
943*e5436536SAndroid Build Coastguard Worker       pWorkBuffer[3] = GetQmfWorkBufferCore4();
944*e5436536SAndroid Build Coastguard Worker     }
945*e5436536SAndroid Build Coastguard Worker 
946*e5436536SAndroid Build Coastguard Worker     if ((size > 4 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[4] == NULL)) {
947*e5436536SAndroid Build Coastguard Worker       /* get work buffer of size QMF_WB_SECTION_SIZE */
948*e5436536SAndroid Build Coastguard Worker       pWorkBuffer[4] = GetQmfWorkBufferCore7();
949*e5436536SAndroid Build Coastguard Worker     }
950*e5436536SAndroid Build Coastguard Worker 
951*e5436536SAndroid Build Coastguard Worker     /* 8. distribute workbuffer over processing channels */
952*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < hgc->nQmfProcChannels; i++) {
953*e5436536SAndroid Build Coastguard Worker       FDK_QmfDomain_FeedWorkBuffer(hqd, i, pWorkBuffer, size_main * i,
954*e5436536SAndroid Build Coastguard Worker                                    QMF_WB_SECTION_SIZE, size_main);
955*e5436536SAndroid Build Coastguard Worker     }
956*e5436536SAndroid Build Coastguard Worker     if (hgc->parkChannel) {
957*e5436536SAndroid Build Coastguard Worker       for (; i < hgc->nInputChannels; i++) {
958*e5436536SAndroid Build Coastguard Worker         FDK_QmfDomain_FeedWorkBuffer(hqd, 1, pWorkBuffer,
959*e5436536SAndroid Build Coastguard Worker                                      size_main * hgc->nQmfProcChannels,
960*e5436536SAndroid Build Coastguard Worker                                      QMF_WB_SECTION_SIZE, size_temp);
961*e5436536SAndroid Build Coastguard Worker       }
962*e5436536SAndroid Build Coastguard Worker     }
963*e5436536SAndroid Build Coastguard Worker 
964*e5436536SAndroid Build Coastguard Worker     /* 9. (re-)init filterbank */
965*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < hgc->nOutputChannels; i++) {
966*e5436536SAndroid Build Coastguard Worker       if ((hqd->QmfDomainOut[i].fb.lsb == 0) &&
967*e5436536SAndroid Build Coastguard Worker           (hqd->QmfDomainOut[i].fb.usb == 0)) {
968*e5436536SAndroid Build Coastguard Worker         /* Although lsb and usb are set in the SBR module, they are initialized
969*e5436536SAndroid Build Coastguard Worker          * at this point due to the case of using MPS without SBR. */
970*e5436536SAndroid Build Coastguard Worker         hqd->QmfDomainOut[i].fb.lsb = hgc->nBandsAnalysis_requested;
971*e5436536SAndroid Build Coastguard Worker         hqd->QmfDomainOut[i].fb.usb =
972*e5436536SAndroid Build Coastguard Worker             fMin((INT)hgc->nBandsSynthesis_requested, 64);
973*e5436536SAndroid Build Coastguard Worker       }
974*e5436536SAndroid Build Coastguard Worker     }
975*e5436536SAndroid Build Coastguard Worker     if (FDK_QmfDomain_InitFilterBank(hqd, 0)) {
976*e5436536SAndroid Build Coastguard Worker       err = QMF_DOMAIN_INIT_ERROR;
977*e5436536SAndroid Build Coastguard Worker     }
978*e5436536SAndroid Build Coastguard Worker   }
979*e5436536SAndroid Build Coastguard Worker 
980*e5436536SAndroid Build Coastguard Worker bail:
981*e5436536SAndroid Build Coastguard Worker   if (err) {
982*e5436536SAndroid Build Coastguard Worker     FDK_QmfDomain_FreeMem(hqd);
983*e5436536SAndroid Build Coastguard Worker   }
984*e5436536SAndroid Build Coastguard Worker   return err;
985*e5436536SAndroid Build Coastguard Worker }
986*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_FreeWorkBuffer(HANDLE_FDK_QMF_DOMAIN hqd)987*e5436536SAndroid Build Coastguard Worker static void FDK_QmfDomain_FreeWorkBuffer(HANDLE_FDK_QMF_DOMAIN hqd) {
988*e5436536SAndroid Build Coastguard Worker   FIXP_DBL **pWorkBuffer = hqd->globalConf.pWorkBuffer;
989*e5436536SAndroid Build Coastguard Worker 
990*e5436536SAndroid Build Coastguard Worker   if (pWorkBuffer[0]) FreeQmfWorkBufferCore6(&pWorkBuffer[0]);
991*e5436536SAndroid Build Coastguard Worker   if (pWorkBuffer[1]) FreeQmfWorkBufferCore1(&pWorkBuffer[1]);
992*e5436536SAndroid Build Coastguard Worker   if (pWorkBuffer[2]) FreeQmfWorkBufferCore3(&pWorkBuffer[2]);
993*e5436536SAndroid Build Coastguard Worker   if (pWorkBuffer[3]) FreeQmfWorkBufferCore4(&pWorkBuffer[3]);
994*e5436536SAndroid Build Coastguard Worker   if (pWorkBuffer[4]) FreeQmfWorkBufferCore7(&pWorkBuffer[4]);
995*e5436536SAndroid Build Coastguard Worker }
996*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_FreeMem(HANDLE_FDK_QMF_DOMAIN hqd)997*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_FreeMem(HANDLE_FDK_QMF_DOMAIN hqd) {
998*e5436536SAndroid Build Coastguard Worker   FDK_QmfDomain_FreeWorkBuffer(hqd);
999*e5436536SAndroid Build Coastguard Worker 
1000*e5436536SAndroid Build Coastguard Worker   FDK_QmfDomain_FreePersistentMemory(hqd);
1001*e5436536SAndroid Build Coastguard Worker 
1002*e5436536SAndroid Build Coastguard Worker   FDK_QmfDomain_ClearFilterBank(hqd);
1003*e5436536SAndroid Build Coastguard Worker 
1004*e5436536SAndroid Build Coastguard Worker   FDK_QmfDomain_ClearConfigured(&hqd->globalConf);
1005*e5436536SAndroid Build Coastguard Worker 
1006*e5436536SAndroid Build Coastguard Worker   FDK_QmfDomain_ClearRequested(&hqd->globalConf);
1007*e5436536SAndroid Build Coastguard Worker }
1008*e5436536SAndroid Build Coastguard Worker 
FDK_QmfDomain_Close(HANDLE_FDK_QMF_DOMAIN hqd)1009*e5436536SAndroid Build Coastguard Worker void FDK_QmfDomain_Close(HANDLE_FDK_QMF_DOMAIN hqd) {
1010*e5436536SAndroid Build Coastguard Worker   FDK_QmfDomain_FreeWorkBuffer(hqd);
1011*e5436536SAndroid Build Coastguard Worker 
1012*e5436536SAndroid Build Coastguard Worker   FDK_QmfDomain_FreePersistentMemory(hqd);
1013*e5436536SAndroid Build Coastguard Worker }
1014